[英]Implicitly calling a constructor of an inaccessible virtual base class
请考虑以下代码。 g ++和clang ++都抱怨(正确地)构造函数A(int)
在D
类中是私有的。 注意,由于A
是D
的虚基类,根据C ++ 11中的§12.6.2/ 7, A
必须在D
类的mem-initializer中初始化 , D
类是派生最多的类。 查看实例 。
class A {
public:
A(int i) : x(i) { }
A() : x(1) {}
int x;
};
class B : private virtual A {
protected:
B(int i) : A(i) { } };
class C : public B, private virtual A {
protected:
C(int i) : A(i), B(i) { }
};
class D : public C {
public:
D() : A(1), C(3) { }
};
int main() {
D d;
}
但是两个编译器都不会理会A
类的默认构造函数在D
也是私有的,即,如果我们为D
定义构造函数,则通常编译和执行代码,如下所示:
D() : C(3) {}
据我所知,这是错误的。
请注意,如果我们定义:两个编译器都无法正确编译:
D() : A(), C(3) {}
但是两个编译器都不打扰
A
类的默认构造函数在D
也是私有的,
不,该默认构造函数不是私有的。 基类A
是私有的,但其默认构造函数是public。
这就是它的工作原理:在ctor-initializer中命名基类时,必须可以访问命名的基类,因为访问控制适用于名称,还有一些特殊的例外,标准表示隐式调用的函数仍然必须是可访问的。
隐式构造基类时,不会命名这些基类。 它们只是默认初始化(每12.6.2p8),默认初始化只检查构造函数是否可访问(每8.5p7)。
您可以通过不使用基类的私有继承名称,但通过使用全局可访问的名称::A
来判断问题是否与基类的名称有关:
D() : ::A(1), C(3) { }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.