Jump to content
  • Advertisement
Sign in to follow this  
mishikel

Using 'this' in base member initializer list

This topic is 4982 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

class A;

class B
{
public:
   B(A* a) : parent(a) { ... }
   A* parent;
};

class A
{
public:
   A() : b(new B(this)) { ... }
   boost::shared_ptr< B > b;
};
Writing something like this generates a level 4 warning using MSVC 8: "warning C4355: 'this' : used in base member initializer list". When is it safe to do this, and when is it not safe?

Share this post


Link to post
Share on other sites
Advertisement
It is safe to do it as long as the object being initialised with this does not try to access a not-yet initialised member (beware of initialistation order - it is the order variables are declared in the class, not the order they are listed in the initialiser list) or use polymorphic behaviour of the non-yet-constructed superclass subclass of this.

See the C++ FAQ Lite.

Edit: I meant subclass, not superclass!

Enigma

Share this post


Link to post
Share on other sites
You might want to consider getting B to create A and then set a pointer to the instance of A itself. This means you don't have write code like the above that's on the verge of being undefined either now or in the future when you add new features because this will always be ok.

Share this post


Link to post
Share on other sites
The problem is that this is really bad encapsulation... it creates a "gotcha" where you could screw things up later by changing things within the class of the called object.

Too bad the compiler doesn't actually walk down the call stack to find out if the bad members or methods are actually used during the delicate phase.

Share this post


Link to post
Share on other sites
Quote:
Original post by Pxtl
The problem is that this is really bad encapsulation... it creates a "gotcha" where you could screw things up later by changing things within the class of the called object.

Too bad the compiler doesn't actually walk down the call stack to find out if the bad members or methods are actually used during the delicate phase.


I agree. Rewriting this code for those very reasons.

Share this post


Link to post
Share on other sites
The specific problem here is the compiler does/can not assume that the constructor B::B(A*) does not access the partially constructed A.

As far as "walking down the call stack", there is no call stack when the code is compiled, and the compiler can predict what code will be executed only in trivial cases. What if B::B(A*) has a conditional statement? How would the compiler know which branch will be executed?

Share this post


Link to post
Share on other sites
Quote:
Original post by Pxtl
Too bad the compiler doesn't actually walk down the call stack to find out if the bad members or methods are actually used during the delicate phase.


Some do! It's just not required.


...
I'm curious to see an alternative implementation for nested-classes. None come to mind.

Share this post


Link to post
Share on other sites
I don't think its bad engineering, its just delicate and should be marked as such. If you need to make links back to objects then thats pretty much the only way to do it. Using a member function opens the code up to the user forgetting to do so. I'll take a compile-time error over a runtime one, thank you.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!