是否仅在创建类的对象时才调用构造函数

Is it that constructor is called only in case an object of a class is made?

本文关键字:调用 构造函数 对象 创建 是否      更新时间:2023-10-16

我现在所知道的,在创建对象时会调用构造函数。我也知道不可能创建抽象类的对象。

但是当我运行这段代码时,我看到以下内容:-

#include <iostream>
using namespace std;
class Pet {
public:
    Pet(){cout<<"in base constructorn";}
    virtual ~Pet() = 0;  //making pet abstract by making drstructor pure virtual
};
Pet::~Pet() {
    cout << "~Pet()" << endl;
}
class Dog : public Pet {
    public:
    Dog(){cout<<"in drvd constructorn";}
    ~Dog() {
        cout << "~Dog()" << endl;
    }
};
int main() {
    Pet* p = new Dog; // Upcast
    delete p; // Virtual destructor call
    return 0;
}

编译并运行时,其输出为:-

in base constructor
in drvd constructor
~Dog()
~Pet()

为什么 Pet 的构造函数被调用,即使它是一个抽象类并且不允许为其创建对象?所以归结为最终仅在对象创建的情况下调用构造函数?

无法创建抽象类的对象

不要拿这个广告垃圾。不能创建实际类型为抽象的对象

但是,如果你实现该类(扩展它并实现其中的所有纯虚拟方法(并实例化新类,则将创建原始抽象基类的对象作为新类的一部分。

继承是一种is-a关系。 Dog是一个Pet.创建Dog 时,将创建一个Pet。但是,您无法自行创建Pet

正确的陈述是"不可能创建抽象类的最派生对象"。但是对象也可以是更多派生对象的基本子对象,在这种情况下,它们仍然需要构造。

(对象可以通过三种方式成为子对象:类类型对象的成员子对象、派生类类型对象的基本子对象或数组的元素。

在您的示例中,您可以创建 Dog 的实例,但不能创建 Pet。即

Pet p; //Not possible, as destructor is abstract.
Dog d; //Allowed, because you derived from pet and ~pet( ) is defined.

一般顺序是,如果创建目标类的对象,则按基类 ->子级别 -> ... -> 目标类的顺序调用构造函数。析构函数遵循相反的顺序。

为了可视化这一点,请考虑目标类是其所有父类的超集。在这里,狗是一套超级宠物。