这似乎是您在 C++ 中经常遇到的情况,但我还没有真正找到答案。
我们有一个基类
Car
和一个成员对象 Engine
。现在我们将 Car
导出为 RaceCar
。那辆赛车当然有一个特殊的引擎SuperEngine
。现在最好的设置方法是什么?
基类:
class Engine{
};
class Car{
public:
Engine* engine;
Car(Engine* e): engine(e){}
};
派生类:
class SuperEngine: public Engine{
};
class RaceCar: public Car{
public:
SuperEngine* engine;
SuperEngine():
engine(new SuperEngine),
Car(engine) // engine is nullptr since this line is called before the above line
{}
}
在上面的例子中,
Car
是用nullptr
初始化的,因为在初始化列表中,基类总是首先被调用,无论初始化列表中的顺序如何(据我所知)。这当然不是我们想要的。
一种解决方法是首先在类外部定义一个
SuperEngine
对象,然后传递它的指针。但如果你有很多成员,这会变得非常难看。例如。 Engine、Throttle、Valve 等。这给出了非常长的构造函数,如果你更改某些内容,则必须更改它 3 次(在 new
所在的类之外、在派生类构造函数中和在基类构造函数中) ).
对我来说,拥有一个派生类似乎是很自然的事情,它使用基类成员的派生类型(例如 Engine 到 SuperEngine)。然而教程或书籍似乎没有涵盖它(或者我只是愚蠢地找到任何内容)。
实现这一目标的最佳方法是什么(以一种也具有物理意义的方式)?应该注意的是,基类中的引擎和派生类中的引擎是相同的(因此派生类不应隐藏基类引擎)。这样
Engine
就可以有一个虚拟方法,例如virtual void fullpower();
。
有没有办法在基类构造函数之前初始化SuperEngine?或者你会把它设置得完全不同吗?期待您的想法!
一个技巧是使用委托构造函数:
class RaceCar: public Car {
public:
SuperEngine* engine;
RaceCar() : RaceCar(new SuperEngine) {}
private:
explicit RaceCar(SuperEngine* se) : Car(se), engine(se) {}
};