在创建大多数派生类的对象时,如何在私有虚拟继承中调用大多数基类的默认构造函数。但是,当在大多数派生类的构造函数初始化列表中提到时,同样不会被调用。
#include<iostream>
using namespace std;
class A
{
public:
A() {cout << "1";}
};
class B: private virtual A
{
public:
B() {cout << "2";}
};
class C: private virtual A
{
public:
C() {cout << "3";}
};
class D: private B, private C
{
public:
D() : A(), B(), C() {cout << "4";}
//D() {cout << "4";}
};
int main()
{
D d1;
cout << "\n";
}
我的问题:
对于下面提到的代码
D() : A(), B(), C() {cout << "4";}
我得到以下编译错误:
错误:'A A A :: A'在此上下文中无法访问
为什么A()构造函数在这里不可访问?
另一方面,下面提到的代码被成功编译并且A()构造函数被调用。
D() {cout << "4";}
该计划的输出是:
的 1234
意味着调用A()构造函数。
那么,为什么在上述两种情况下调用构造函数A()的行为会发生变化?
我所知道的:
(1)当我做B&amp; B的'公共虚拟继承'时C,即使它在大多数派生类的构造函数初始化列表中提到,也会调用大多数基类的默认构造函数。 以下语句编译。 D():A(),B(),C(){cout&lt;&lt; “4”;}
(2)在虚拟继承中,虚拟基类的构造函数直接从大多数派生类的构造函数中调用。
对我来说,虚拟继承可能是一个概念问题。请帮助我理解这一点,并为此分享好的参考资料。
答案 0 :(得分:0)
答案 1 :(得分:0)
正如评论中提到的,A()
不能从 D()
显式调用,因为 A()
是 B
和 C
的私有成员。 private
继承允许访问公共成员和受保护成员,并使他们成为私有。无论是私有的,都不会被继承。所以关键是继承时的访问说明符,不是虚拟继承。您可以尝试从示例中删除 virtual
。该程序将打印 12134
,因为虚拟继承提供了一个公共基础对象。
如果有人想知道为什么程序会输出 1234
(或非虚拟情况下的 12134
),我邀请他们阅读有关派生类的构造顺序:
https://www.learncpp.com/cpp-tutorial/order-of-construction-of-derived-classes/