C ++ - 为什么默认构造函数甚至在私有继承中也能工作

时间:2017-04-30 05:58:21

标签: c++ inheritance

The following question带来了这种现象,即使在私有的继承模式下,也会注意到构造函数的调用位置。

我在钻石问题上尝试过,然后通过breaking the diamond rule and just keeping virtual inheritance更简单。

然后我做了一个简单的3级继承示例,我将在下面展示(C继承BB继承C - 两者都在< strong> 私有继承 )并且仍在调用A的构造函数。

A()中不应该private C无法访问吗?

#include<iostream>
using namespace std;
class A
{
public:
     A(){ cout << "1"; }
};

class B:  A
{
public:
    B(){ cout << "2"; }
};

class C:  B
{
public:
   C(){ cout << "3"; }
};


int main()
{
   C c1;
}

Output: 123 (您还可以查看代码并输出here

P.S :我已经尝试了正常情况(此处给出)和virtual继承,即使使用&#34; Diamond-Problem&#34; - 每次答案都是一样的。

1 个答案:

答案 0 :(得分:2)

没有涉及虚拟继承,所以它不能由C来构造A.因此,C的构造函数调用B的构造函数,B又调用A的构造函数。假设违反访问说明符的行为。

对于虚拟继承的情况,我们注意到

指定了从成员初始化列表中省略的子对象的构造。

[class.base.init/9]

  

在非委托构造函数中,如果给定的可能构造的子对象不是由mem-initializer-id指定的(包括没有mem-initializer-list的情况,因为构造函数没有ctor-initializer),那么

     
      
  • ...
  •   
  • ...
  •   
  • 否则,实体默认初始化。
  •   

所以上面的子句似乎表明默认的初始化必须发生,并且访问说明符应该被丢弃。

重要的是要记住,访问说明符是限制程序在类定义中引用的内容,它们不会阻止编译器发出正确的代码,例如上面条款所要求的。

但是,如果您曾尝试显式调用虚拟基础的默认构造函数,那么它将是格式错误的,like this

#include<iostream>
using namespace std;
class A
{
public:
     A(){ cout <<"1";}
};

class B:  virtual A
{
public:
    B(){cout <<"2";}
};

class C:  B
{
public:
   C() : A() {cout<<"3";}
};

int main()
{
   C c1;
}

给出了:

prog.cpp: In constructor ‘C::C()’:
prog.cpp:18:10: error: ‘class A A::A’ is inaccessible within this context
    C() : A() {cout<<"3";}
          ^
prog.cpp:4:1: note: declared here
 {
 ^

为什么呢?因为现在你的程序试图明确地破坏访问,而不是编译器正在完成它的工作。