Question

I have a class hierarchy where I know that a given class (B) will always be derived into a second one (D). In B's constructor, is it safe to statically cast the this pointer into a D* if I'm sure that nobody will ever try to use it before the entire construction is finished? In my case, I want to pass a reference to the object to yet another class (A).

struct A
{
    D & d_;

    A(D & d) : d_(d) {}
};

struct D; //forward declaration

struct B
{
    A a;

    B() : a(std::static_cast<D&>(*this)) {}
};

struct D : public B
{};

Is this code safe?

Was it helpful?

Solution 3

@AProgrammer's answer made me realized that the static_cast could be easily avoided by passing the this pointer from the derived class to the base class. Consequently, the question boils down to the validity of the this pointer into the member-initializer-list.

I found the following note in the C++ Standard [12.6.2.7]:

[Note: because the mem-initializer are evaluated in the scope of the constructor, the this pointer can be used in the expression-list of a mem-initializer to refer to the object being initialized. ]

Therefore, using this in the member-initializer-list is perfectly valid, so I think the code presented is safe (as long as no members of D are accessed).

OTHER TIPS

I didn't find anything about that. I've trouble to find reasons for which your code would be unsafe while this is safe:

struct B
{
    A a;

    B(D& d) : a(d) {}
};

struct D : public B
{
    D() : B(*this) {}
};

but I'd probably still use the form I present here.

No, it is not. Constructors for D's data members didn't run yet.

Since D's membrs aren't constructed, D isn't fully constructed yet, so technically, a reference to D should be invalid. I expect that to be no problem on most implementations, but still.

I'd like to suggest a better mechanism, but I guess "better" depends a lot on actual details.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top