20

In the following program body cosists of a vector of pointers. Points is a struct of x,y,z coordinates and a point_id. I believe as body is passed by const reference, the following step should produce an error. BUt the program is running without any problem. Can you please explain me why is this.

void readOutFile(const Body& body, int n){

    ....

    body.bp[0]->points.push_back(Point_id(p,i));
}
user829209
  • 219
  • 2
  • 7
  • 2
    `body` is passed as `const` but there is no way for the compiler to know that `body.bp[0]->points` should be `const` as well. – wroniasty Jun 11 '12 at 08:34
  • It will run ok and const error will be a compile time error, not a run time error. – ctrl-alt-delor Jun 11 '12 at 10:24
  • 3
    In C++, const is shallow, not deep. So it effects the object but not its associations. It means you can only call const methods. But const methods can change other objects, always use methods in interface, and use a good lint tool to check for deep const. – ctrl-alt-delor Jun 11 '12 at 10:27
  • @richard what does const is shallow means ? is there concept: a shallow const and deep const as well? – zinking Jun 15 '12 at 03:40
  • Deep and shallow const, is like deep and shallow copy. Shallow refers to the object alone. Deep refers to the object and all objects it refers to. I.E. A shallow const collection/object is an invariant collection/object of variant objects. A deep const collection/object is an invariant collection/object of deep const objects. (note the recursive definition). Also note that if an object is deep const, it would pass a shallow const test. (this is not true of copy) – ctrl-alt-delor Jun 15 '12 at 08:38

4 Answers4

39

Here's the issue:

body.bp[0]->points.push_back(Point_id(p,i));
          ^^

Indirecting through a pointer removes any constness; rather, the constness of the result is dependent on the type of the pointer.

T *t;              // pointer to T: can modify t and (*t)
const T *t;        // pointer to const-T: can modify t but not (*t)
T *const t;        // const-pointer to T: can modify (*t) but not t
const T *const t;  // const-pointer to const-T: can't modify either t or (*t)
ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • 3
    I never realized this but it makes sense. Constness propagates to the member pointer but not it its contents as well. – Paul Manta Jun 11 '12 at 08:38
16

This is one of best example which shows why data members should not be public.

here, body is constant hence its data members must not be changed, but in body.bp[0]->points point is being changed which is not the member of Body.Hence no const violation.

Eight
  • 4,194
  • 5
  • 30
  • 51
  • 5
    To me, this is an example of why **member pointers** should not be public. Nothing wrong with public "value" data members. – ulidtko Jun 11 '12 at 12:06
6

Only body is constant.

body.bp[0]->points is no way affected by the constantness of body

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
6

Yes, body is constant. That means that no non-const member functions may be called, and no member variables be modified.

Neither is being done. The only member of body used is body.bp[0], which is not changed either, but merely used to get at points, which might or might not be constant...

Corrolary: Don't make data members public.

DevSolar
  • 67,862
  • 21
  • 134
  • 209