只有在创建类的对象的情况下才调用构造函数吗?

时间:2012-03-31 08:55:41

标签: c++ inheritance constructor

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

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

#include <iostream>

using namespace std;

class Pet {
public:
    Pet(){cout<<"in base constructor\n";}

    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 constructor\n";}

    ~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的构造函数被调用,即使它是一个抽象类而且不允许创建对象?所以它归结为最终是仅在对象创建的情况下调用的构造函数?

3 个答案:

答案 0 :(得分:6)

  

无法创建抽象类的对象

请勿使用此广告。 您无法创建实际类型为抽象的对象

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

继承是is-a关系。 DogPet。创建Dog时,您需要创建Pet。但是你不能自己创建Pet

答案 1 :(得分:2)

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

(对象可以是三种方式的子对象:类型对象的成员子对象,派生类型对象的基础子对象或数组的元素。)

答案 2 :(得分:1)

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

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

一般顺序是,如果您创建目标类的对象,则按基类的顺序调用构造函数 - &gt;儿童等级 - &gt; ... - &gt;目标类。析构函数遵循相反的顺序。

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