1

Say I have a class Foo that has a member function which returns a non-const reference, that itself runs a member function that uses a const this pointer:

class Foo{ public: Foo& display(std::ostream& os) { do_display(os); return *this; } private: void do_display(std::ostream& os) const { os << contents; } std::string contents; } 

When display runs do_display, the this pointer gets implicitly converted to a pointer to const. Why is it, then, that when do_display terminates, display is still able to change the object it was called on? As far as I know, it's not possible to assign a pointer to const to a pointer to non-const normally. Any insight is appreciated.

5
  • 3
    You can think of it like a parameter. if it has const added for one function, that doesn't affect the caller. Commented Feb 21, 2014 at 15:24
  • only do_display can't change the object. display can. there's no magic here, as this is passed as first (hidden) parameter. Commented Feb 21, 2014 at 15:26
  • Non-const methods can change the object just fine, even if they call a const one. A method is just like another function with a hidden "first" parameter. Commented Feb 21, 2014 at 15:28
  • you pass a parameter by value (the pointer's one) so you can do whatever you want Commented Feb 21, 2014 at 15:29
  • Thanks, that makes sense. I wasn't sure if "this" was an implicit parameter or something that gets implicitly returned. Commented Feb 21, 2014 at 15:31

2 Answers 2

2

Converting the non-const pointer in display in order to pass it to do_display creates a new pointer of a different type; it doesn't change the type of the existing pointer. Passing this to a member function is very similar to passing an argument to a non-member function:

// A non-const member function receives `this` as a non-const pointer Foo& display(Foo * this, std::ostream & os) { // Pass a copy of `this`, converted to `Foo const *` do_display(this, os); // The local `this` is still `Foo *` return *this; } // A const member function receives `this` as a const pointer void do_display(Foo const * this, std::ostream & os) {os << this->contents;} 
Sign up to request clarification or add additional context in comments.

7 Comments

Did you experience the copying with newer compilers? I currently work mostly with the old-fashioned ones.
@Wolf: You don't "experience the copying", since the mechanism for passing this is hidden. The point is that passing it to another member function doesn't change its type in the calling function, in the same way that passing a normal argument wouldn't change the type of any local variables.
Ok, that's what I forgot: The this pointer is so omnipresent, that I didn't even remember that it has to be passed to member functions, and in cases like in the OP's example, the call will surely be optimized.
Shouldn't the first argument to do_display be declared as const Foo* this rather than Foo const* this? I always thought the this pointer was a "pointer to constant object".
@jia103: Both are equivalent. I usually put the const after the thing it qualifies for consistency; but you can put it before the first thing if you want.
|
0

In C++ const access is often only a compile-time attribute [1] that is introduced to ease the control of the object's state. [2]

The method do_display() does not change anything of this but it restricts the access to read-only in its scope. After the call of the do_display() method returned, the access is read-write as before in the scope of the display() method.


[1] that's the reason for the option to cast const away, which can be considered safe if the constness is only a declarative one.

[2] see Item #3 in Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition): Scott Meyers or for example Const Correctness - C++ Tutorials - Cprogramming.com

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.