c – 隐式调用不可访问的虚拟基类的构造函数

考虑下面的代码g和clang(正确地)抱怨(构造函数A(int))在类D中是私有的.注意,由于A是D的虚拟基类,必须在D类的mem初始化器中初始化A,最多派生类,根据C.12中的§12.6.2/ 7.见 live example.
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;
}

但是,两个编译器都不用担心D的认构造函数在D中也是私有的,即如果我们定义D的构造函数,那么它们将正常地编译和执行代码,如下所示:

D() : C(3) {}

这是错的,据我所知.

请注意,如果我们定义了两个编译器,则无法正确编译(正确):

D() : A(),C(3) {}

解决方法

But both compilers don’t bother with the fact that the default constructor for class A is also private in D,

不,认构造函数不是私有的.基类A是私有的,但它的认构造函数是public.

这就是为什么它的工作原理:当在ctor-initializer中命名基类时,命名的基类必须可访问,因为访问控制适用于名称,还有一些特殊的异常,其中标准表示隐式称为函数仍然必须可访问.

当基类被隐式构造时,这些基类不被命名.它们只是认初始化(根据12.6.2p8),认初始化仅检查构造函数是否可访问(根据8.5p7).

您可以通过不使用基类的私有继承的名称,但通过使用全局可访问的名称来表明问题是基类的名称:: A:

D() : ::A(1),C(3) { }

Live example

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...