The following question带来了这种现象,即使在私有的继承模式下,也会注意到构造函数的调用位置。
我在钻石问题上尝试过,然后通过breaking the diamond rule and just keeping virtual inheritance更简单。
然后我做了一个简单的3级继承示例,我将在下面展示(C
继承B
和B
继承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; - 每次答案都是一样的。
答案 0 :(得分:2)
没有涉及虚拟继承,所以它不能由C来构造A.因此,C的构造函数调用B的构造函数,B又调用A的构造函数。假设违反访问说明符的行为。
对于虚拟继承的情况,我们注意到
指定了从成员初始化列表中省略的子对象的构造。在非委托构造函数中,如果给定的可能构造的子对象不是由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
{
^
为什么呢?因为现在你的程序试图明确地破坏访问,而不是编译器正在完成它的工作。