首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么大多数基类( virtual )的默认构造函数在创建大多数派生类的对象时没有在私有虚拟继承中被调用?

为什么大多数基类( virtual )的默认构造函数在创建大多数派生类的对象时没有在私有虚拟继承中被调用?
EN

Stack Overflow用户
提问于 2017-05-05 05:57:02
回答 2查看 431关注 0票数 1

在创建大多数派生类的对象时,如何在私有虚拟继承中调用大多数基类的默认构造函数。但是,在大多数派生类的构造函数初始化程序列表中提到的情况下,也不会调用相同的值。

代码语言:javascript
复制
#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";
}

我的问题:

用于以下代码

代码语言:javascript
复制
D() : A(), B(), C() {cout << "4";}

下面是编译错误:

错误:‘A类A::A’在此上下文中无法访问

为什么A()构造函数在这里不可访问?

另一方面,下面提到的代码被成功编译,A()构造函数被调用。

代码语言:javascript
复制
D()  {cout << "4";}

程序的输出是:1234意味着A()构造函数正在被调用。

那么,为什么在上述两种情况下调用构造函数A()的行为会发生变化呢?

我所知道的:

(1)当我对B& C进行“公共虚拟继承”时,即使大多数派生类的构造器初始化列表中提到了它,也会调用大多数基类的默认构造函数。意思是下面的语句编译。D():A(),B(),C() {cout << "4";}

(2)在虚拟继承中,直接从派生类的构造函数中调用虚拟基类的构造函数。

对我来说,虚拟继承可能是一个概念问题。请帮助我理解这一点,并分享好的参考资料。

EN

回答 2

Stack Overflow用户

发布于 2017-05-05 06:11:24

从D的角度来看,A是私有的,但即使不是,D试图构造A也是不正确的,它只应该构造直接的基类和实例成员对象。B和C都将负责A的默认构造。

票数 0
EN

Stack Overflow用户

发布于 2021-03-26 20:26:16

正如注释中提到的,A()不能从D()显式调用,因为A()BC的私有成员。private继承提供了对公共成员和受保护成员的访问,并使它们成为私有。不管是私人的,都不是遗传的。因此,关键是在继承期间访问说明符,而不是,而不是虚拟继承。您可以尝试从示例中删除virtual。该程序将打印12134,因为虚拟继承提供了一个公共的基本对象。

如果有人想知道为什么程序输出1234 (或非虚拟情况下的12134 ),我请他们阅读派生类的构造顺序:https://www.learncpp.com/cpp-tutorial/order-of-construction-of-derived-classes/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43797505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档