C++派生类中的派生成员对象以及如何初始化

nqwrtyyt  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(98)

这似乎是你在C++中经常遇到的情况,但我还没有真正找到答案。
我们有一个基类Car和一个成员对象Engine。现在我们推导出CarRaceCar。那辆赛车当然有一个特殊的发动机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对象,然后传递它的指针。但如果你有很多成员,这会变得非常丑陋。例如发动机、节气门、气门等。这给出了非常长的构造函数,如果你改变了什么,你必须改变它3次(在new所在的类之外,在派生类构造函数和基类构造函数中)。
对我来说,拥有一个派生类似乎是一件很自然的事情,它使用基类成员的派生类型(如Engine到SuperEngine)。然而,它似乎没有被教程或书籍所涵盖(或者我只是愚蠢地找到任何)。
实现这一点的最佳方式是什么(以一种物理意义上的方式)?应该注意基类中的引擎和派生类中的引擎是相同的(所以派生类不应该隐藏基类引擎)。所以Engine可以有一个虚方法,例如virtual void fullpower();
有没有办法在基类构造函数之前初始化SuperEngine?或者你会把它设置成完全不同的?期待您的想法!

2exbekwf

2exbekwf1#

一个技巧是使用委托构造函数:

class RaceCar: public Car {
public:
    SuperEngine* engine;
    RaceCar() : RaceCar(new SuperEngine) {}
private:
    explicit RaceCar(SuperEngine* se) : Car(se), engine(se) {}
};

相关问题