繁体   English   中英

隐式调用无法访问的虚拟基类的构造函数

[英]Implicitly calling a constructor of an inaccessible virtual base class

请考虑以下代码。 g ++和clang ++都抱怨(正确地)构造函数A(int)D类中是私有的。 注意,由于AD的虚基类,根据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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM