views:

145

answers:

2

context 1: class D : public B1, public B2{};

context 2: B2 takes B1 to initialize: B2( B1 * ) //B2's constructor

my question is in D's initialization list:

D::D() : B1(), B2( ? )... What should be in ?

I don't want to put " (B1*)this " in the ? place, because it's no good to use "this" in initialization list. And since B1 part has been initialized, it makes sense to use it.

What should I do ?

+3  A: 

It's OK to use the B1 part of this because it is already initialized. §12.6.2/5: "direct base classes shall be initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers)."

The base-specifier-list here is is class D : public B1, public B2, and the mem-initializer-list is D::D() : B1(), B2( … ).

I would say that this has "code smell," though.

EDIT: Now I understand your concern, whether this is undefined outside the body of the constructor, which doesn't include the member initializers. The language allowing this is buried between two examples and I missed it at first. Paragraph 7: "Names in the expression-list of a mem-initializer are evaluated in the scope of the constructor for which the mem-initializer is specified."

If B2 actually needs to retain a pointer to a B1, and that pointer will always point inside the most-derived object, consider virtual inheritance.

class B1 {};
class B2 : virtual B1 {}; // under the hood, B2 has a pointer to B1.
class D : public virtual B1, public B2 {}; // D has a pointer too
 // Only the most-derived class (the one actually used for instantiation)
 // implements space for and initialization of the B1.
Potatoswatter
In my case, B1 and B2 are not in a inheritance relationship, I don't want to change B2 for the purpose of solving this issue.
JQ
+1  A: 

This is risky code. As pointed out before, B1 is constructed before B2, so you can safely do this, but if the class definition changes that will no longer be the case, and it is in an unrelated place in the code, so you can't see the code you're breaking when you break it.

I'd look closely at this design - Is it possible to change it to make this unnecessary? Can you move things into members to encapsulate rather than inherit - is D really a B1 and a B2?

Stewart
It's common seen that one member has dependency on another, if definition changes, developers hold the responsibility to change implementation.I could change my design, it's easy, but I want to discover the technical side of this issue, because it makes sense.
JQ
@JQ: you said "member" instead of "base." If they're actually members, you don't have this problem. Are they?
Potatoswatter
@Potatoswatter: Again, I repeat following"I could change my design, it's easy, but I want to discover the technical side of this issue, because it makes sense"
JQ