C++ 是否有基类';用派生的构造函数和析构函数调用s的构造函数和析构函数?

C++ 是否有基类';用派生的构造函数和析构函数调用s的构造函数和析构函数?,c++,C++,我有一个名为MyBase的类,它有一个构造函数和析构函数: class MyBase { public: MyBase(void); ~MyBase(void); }; 我有一个叫做香蕉的类,它扩展了MyBase,如下所示: class Banana:public MyBase { public: Banana(void); ~Banana(void); }; 香蕉中新构造函数和析构函数的实现是否覆盖了MyBase构造函数,或者它们是否仍然存在,并在香蕉构造函

我有一个名为MyBase的类,它有一个构造函数和析构函数:

class MyBase
{
public:
    MyBase(void);
    ~MyBase(void);
};
我有一个叫做香蕉的类,它扩展了MyBase,如下所示:

class Banana:public MyBase
{
public:
    Banana(void);
    ~Banana(void);
};
香蕉中新构造函数和析构函数的实现是否覆盖了MyBase构造函数,或者它们是否仍然存在,并在香蕉构造函数/析构函数执行之前或之后被调用


谢谢,如果我的问题看起来很傻,我很抱歉。

您缺少继承类型:

改变

class Banana:MyBase
致:

至于

新政策的实施情况如何 香蕉中的构造函数和析构函数 覆盖MyBase,或者 仍然存在,并被称为说之前 或者在香蕉之后/ 析构函数执行

继承的顺序从下到上执行,这意味着将首先调用MyBase,然后调用Banana。如果您有另一个子类,它将被称为last

举个例子:

class RottenBanana : public Banana
继承链现在是RottenBanana->Banana->MyBase


此类的构造函数将从MyBase开始调用,然后从Banana开始调用,然后再调用RottenBanana。

基类构造函数将始终在派生构造函数之前调用。 基本析构函数将在Dervided析构函数之后调用

您可以在派生构造函数上指定所需的基本构造函数,如果不是,将执行默认构造函数

如果您定义了其他构造函数,但不是默认构造函数,并且没有在派生构造函数上指定要执行的构造函数,那么它将尝试使用不存在的默认构造函数,并将导致编译崩溃


发生上述情况的原因是,一旦声明一个构造函数,就不会生成默认构造函数。

构造函数不能被重写。不能在派生类中声明基类构造函数。类构造函数必须先调用基类中的构造函数(如果没有明确说明,则调用默认构造函数),然后再调用其他构造函数

为了能够正确清理派生类,应该将基类析构函数声明为
virtual

virtual ~MyBase() { ... }
应该说

class Banana : public MyBase
{
public:
    Banana(void);
    ~Banana(void);
};

派生类的构造函数在基类的构造函数之后被调用。析构函数的调用顺序相反。

在继承树中,构造函数是自上而下调用的。这使得派生构造函数在尝试使用基对象的任何属性之前,可以指望基对象已完全初始化

析构函数的调用顺序与构造函数的调用顺序相反,原因相同——派生类依赖于基类,但基类不依赖于派生类


如果存在通过指向基类的指针销毁对象的任何可能性,则必须声明所有析构函数
virtual

构造函数和析构函数都是特殊的成员函数。一般来说,您会在任何地方看到构造从层次结构中派生最少的类型一直到派生最多的类型。这实际上是构造函数执行完成的顺序,而不是构造的开始方式

构造函数的初始化列表执行顺序保证,虽然最派生对象的构造函数将是第一个开始执行的构造函数,但它将是最后一个完成的构造函数

实例化对象时,首先调用与构造调用匹配的派生度最高的构造函数。匹配的最派生构造函数的初始化列表将启动,并且初始化列表具有固定的顺序:首先调用继承列表中按顺序或外观排列的基类的构造函数。然后按照成员属性构造函数在类声明中出现的顺序(而不是它们在初始化列表中出现的顺序)调用它们。在整个初始化列表(在每个级别)完成后,将执行构造函数体块,然后完成构造函数调用

在最派生的析构函数完成执行后,所有基本析构函数都将按与构造相反的顺序调用。破坏发生的顺序与构造完全相反

析构函数在另一方面是特殊的:它们不能被重写。调用类的最派生析构函数时,它将完成析构函数体的执行,之后所有成员属性析构函数将按与创建相反的顺序调用。在最派生的析构函数完成并完成了最派生对象的成员析构函数后,其最直接基的析构函数按与构造相反的顺序开始,析构函数体将执行,然后成员属性析构函数等等。。。最后,所有构造元素都将被销毁

多态类的析构函数应该是虚拟的

上面的销毁描述从调用最派生的析构函数开始。这可以通过在指向最派生类型的指针上调用
delete
来实现,当自动对象超出范围时,或者当对象通过析构函数为虚拟的基类
delete
d时

如果忘记在基类中添加析构函数关键字,并试图通过指向基类的指针删除派生对象,则将直接调用基类析构函数,这意味着层次结构中指针类型下的所有子对象都不会正确销毁。通过指向基类型的指针删除对象的所有继承层次结构必须具有虚拟析构函数。作为一般的经验法则,如果您已经有了任何虚拟方法,那么使析构函数虚拟化的成本可以忽略不计,并且是一个安全的网络。许多编码指南强制要求继承层次结构中的析构函数必须是虚拟的。有些甚至要求所有析构函数都是虚拟的,这有av的意图
class Banana : public MyBase
{
public:
    Banana(void);
    ~Banana(void);
};
class EEGMode {
public:

   EEGMode()  { setAllPixelsToColor(BLUE); delay(1000); }
   virtual ~EEGMode()  { setAllPixelsToColor(RED); delay(1000); }

};


class EEGModeRGB : public EEGMode {
public:

    EEGModeRGB()  { setAllPixelsToColor(GREEN);  delay(1000); }
    virtual ~EEGModeRGB()  { setAllPixelsToColor(YELLOW); delay(1000); }

};