Use super class's address/pointer in initialization list
context 1: class D : public B1, public B2{};
context 2: B2 tak开发者_JS百科es 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 ?
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.
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?
精彩评论