2016-12-29 87 views
4

代码打印所有的构造函数。我读到构造函数在我们从另一个类派生一个类时没有被继承。那么为什么创造cba为什么构造函数被调用,如果他们没有被继承?

class A 
{ 
public: 
    A() { cout << "A's constructor called" << endl; } 
}; 

class B 
{ 
public: 
    B() { cout << "B's constructor called" << endl; } 
}; 

class C: public B, public A // Note the order 
{ 
public: 
    C() { cout << "C's constructor called" << endl; } 
}; 

int main() 
{ 
    C c; 
    return 0; 
} 
+3

[C++超类构造函数调用规则]的可能重复(http://stackoverflow.com/questions/120876/c-superclass-constructor-calling-rules) – Soeren

回答

5

当您阅读文件说构造函数是“不继承”,它的意思是,如果类A定义构造函数A::A(int x),然后子类B不会自动有一个构造函数的int

但是,仍然需要初始化父类的值;否则,父对象可能处于无效状态。构造函数用于初始化类,因此意味着一个的父类的构造函数必须从子构造函数的初始化程序列表被调用。如果父类具有默认构造函数,那么默认情况下会调用该构造函数。这就是你在例子中看到的。如果家长不提供一个默认的构造函数,你必须指定要叫哪一个:

class A 
{ 
public: 
    A(int x) { cout << "A's constructor called" << endl; } 
}; 

class C: public A 
{ 
public: 
    C() 
    : A(7) /* compilation will fail without this line */ 
    { cout << "C's constructor called" << endl; } 
}; 
0

构造调用构造函数在传统意义上是不能继承的。

类是继承的。

但是为了构建一个类,需要调用它的构造函数。这是它的工作。硬性规则,没有例外。

当您从第二个类继承一个类时,构造第一个类需要构造第二个类。因为第一类总是包含第二类。另一个硬性规则,没有例外。这就是“继承”的意思。

所以,构造第一个类将调用它的构造函数。然后,为了构建第二个类,它的构造函数也需要被调用(实际上第二个类是先构造的,然后是第一个类的构造)。

这就是为什么两个构造函数都会被使用。

0

构造函数当类继承时调用。除此之外,继承基本上给出了派生类实例的匿名基类成员实例。这些实例需要被构造,以便它们的构造函数被调用。

0

“构造函数不能被继承”的意思,C类应,将有它自己的构造函数,尽管事实有B的构造函数,它将不能使用B的构造函数而不是C的构造函数。而这正是你得到的:你得到所有父类的构造函数。

当你有类的层次结构,并从一个构造对象时,将从基础开始,所有他的父母将有顺序构造。

当你要摧毁它们时,从他开始,他和他的所有父母将会连续遭到毁灭。

按规则:第一次创建 - 最后被破坏。

0

通过不继承,C++ 11种标准手段本

class A 
{ 
    public: 
     A(int x) {} 
}; 

class B: public A 
{ 
}; 

int main(void) 
{ 
    B b(5); 
    return 0; 
} 

这将无法编译因为A(int)不被继承。您可以定义B通过

class B: public A 
{ 
    using A::A; 
}; 

在你的情况明确地继承A(int)您所定义的所有默认的构建函数,并明确定义与否,仍然存在,将被命名为对象初始化的部分原因是由于您的C c宣言。

0

C++继承基本上创建了一个由其超类的部分组成的类。例如:

class A { 
    public: 
     A() { 
      std::cout << "Constructor A" << '\n'; 
     } 
}; 

class B : public A { 
    public: 
     B() { 
      std::cout << "Constructor B" << '\n'; 
     } 
}; 

class C : public B { 
    public: 
     C() { 
      std::cout << "Constructor C" << '\n'; 
     } 
}; 

C类实际上是C类,具有B类部分和A类部分。所以为了构造类C,我们需要通过调用这些部分的构造函数来构造它的每个部分。这些构造函数的顺序是从最基类到最派生类(在本例中为A到C)。最基础的是继承树顶部的类,而最基础的类是底部的类。

同样的规则也适用于析构函数。唯一的区别是,destrutors从大多数派生到最基础(C到A)。

2

我读到,当我们从另一个类

这是正确的派生类的构造函数是不能继承的。但是,你似乎误解了这个意思。

比方说,你有:

struct A 
{ 
    A(int) {} 
}; 

struct B : A 
{ 
    B() : A(0) {} 
}; 

鉴于上述情况,你将无法使用:

B b(10); 

因为A(int)不受B继承。

这是你误会的症结所在。

从B那么为什么的C创建正在调用构造函数和一个

然而,当你构建一个BB构造函数被调用,以初始化它的成员。还必须调用A的构造函数,以便可以初始化对应于AB的子对象。

有几种方法可以初始化A-部分B

  1. 您可以通过使用语法使用的A构造函数中显式成员初始化列表:

    B() : A(0) {} 
    
  2. 离开成员初始化空,在这种情况下A默认构造函数被调用。

    B() {} 
    

    这相当于:

    B() : A() {} 
    

    在我所呈现的例子中,这将导致在一个编译错误因为A默认构造已经通过提供另一个构造比所述不同删除默认构造函数。

回来到您的落实C默认构造函数,你必须:

C() { cout << "C's constructor called" << endl; } 

这相当于

C() : B(), A() { cout << "C's constructor called" << endl; } 

B::B()A::A()被调用时的C实例被构造。

相关问题