2017-07-16 117 views
0

在运行下面的代码,为何是基类的构造函数导出的第一即使我们首先声明派生类的对象。为什么基类的构造函数首先调用?

#include<iostream> 

using namespace std; 

class base { 
    public: 
    base() 
    { cout<<"Constructing base \n"; } 
    ~base() 
    { cout<<"Destructing base \n"; } 
}; 

class derived: public base { 
    public: 
    derived() 
    { cout<<"Constructing derived \n"; } 
    ~derived() 
    { cout<<"Destructing derived \n"; } 
}; 

int main(void) 
{ 
    derived *d = new derived(); //d is defined ahead of the base class object 
    base *b = d; 
    delete b; 

    return 0; 
} 
+0

你还会期待什么?为什么? – user0042

+2

提示:在'derived'里面有一个'base' **子对象**。 – StoryTeller

+0

问题不清楚。你可以解释吗? – MoraRockey

回答

4

继承的表示“是”的关系,让derived类的所有对象都是base类的对象。 derived对象都认为base对象做数据和方法,再加上数据和方法在derived类声明明确宣布。

根据类的实现编写Derived类是完全可能的(也是常见的)。例如,假设我们有

class Base { 
public: 
    Base() { n = 5; } 
    int GetN() const { return n; } 
private: 
    int n; 
}; 

class Derived : public Base { 
public: 
    Derived() { m = GetN() * 2; } 
    int GetM() const { return m; } 
private: 
    int m; 
}; 

现在我们所期待

Derived* d = new Derived(); 
std::cout << d->GetM() << std::endl; 

打印10,这是它应该做的(除非我的一部分的任何错误)到底是什么。这是一个完全合理的(如果有点做作)的事情。

语言可以得到这样的代码能够正常工作的唯一途径是构建Derived类型的对象的时候,Derived构造函数之前运行Base构造。这是因为Derived构造函数依赖于能够调用GetN()方法,它继承自Base,其正确功能取决于数据成员n已在Base构造函数中正确初始化。

总之,构造任何Derived对象时,C++必须首先构造它为Base对象,因为Derived是-一个Base和通常将取决于它的实现和数据。

当你

base* b = d; 
在你的代码

,你声明一个变量b是类型的“指针base对象”,然后初始化与d持有相同的内存地址此变量。编译器不介意你这样做,因为所有derived对象是base对象,所以它使您可能要正确对待db感。这里的对象实际上并没有发生什么,它只是一个指针变量的声明和实例化。对象指向d已经是一个base对象,因为所有derived对象是基本对象。

注意,此解释是故意有点模糊圆的边缘和是远不在C++基类和派生类之间的关系的完整说明。你会想看看其他文章/书籍/标准。我希望这对初学者来说是相对容易理解的。

相关问题