简体   繁体   中英

Pass member of derived class into constructor of base class

I have an abstract base class parent that owns an abstract base class child, and a corresponding derived parent that owns a derived child.

I want to be able to construct the derived child inside my derived parent's initialization, while also keeping a reference to the derived child itself - but this isn't straightforward. As I need to initialize the base first, I cannot pass in an already initialized reference to my derived child into the base's constructor.

I can dynamic_cast the base class' base pointer to my derived child back into a derived-type pointer to keep as a member, but this cannot be a sane approach. Is there a pattern for this kind of thing?

Ex.

This is what I'd like to be able to do, but obviously cannot:

DerivedParent::DerivedParent():
    _derivedChild(new DerivedChild()),
    BaseParent(_derivedChild)
{}

While this is what works, but obviously isn't sensible:

DerivedParent::DerivedParent():
    BaseParent(new DerivedChild()),
    _derivedChild(dynamic_cast<DerivedChild*>(_baseChild))
{}

Is there a pattern for this kind of thing, or am I doing something fundamentally silly?

First and foremost, why do you need to do it? If you need some properties from the base class, why not pass it to the constructor of the child? Or mark the attributes as protected and access it in the child class?

The base class should not know the child class. It's the O 'Open/Closed' principle of SOLID. That's means that every time you add a child class, you must change the base class.

So, the child should have everything it need to be initialized correctly.

With BaseParent having a _baseChild member, your second solution of _derivedChild(dynamic_cast<DerivedChild*>(_baseChild)) is fine. Since you know the type will match, you can also use static_cast instead. In fact, since you know the dynamic type of _baseChild will always be DerivedChild , you can just replace this->_derivedChild in member functions with static_cast<DerivedChild*>(this->_baseChild) (maybe behind a getter function).

You can also use a delegating constructor to avoid the cast:

DerivedParent() : DerivedParent(new DerivedChild()) {}

private:
DerivedParent(DerivedChild* derivedChild) :
    BaseParent(derivedChild), _derivedChild(derivedChild) {}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM