首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >多重继承的构造函数会被多次调用吗?

多重继承的构造函数会被多次调用吗?
EN

Stack Overflow用户
提问于 2011-09-14 01:17:46
回答 3查看 11.2K关注 0票数 20

多重继承的构造函数会被多次调用吗?构造函数是按什么顺序调用的?这取决于继承列表中的顺序吗?

这里有一个例子(这只是为了让情况变得清晰,没有实际的例子)。

class Base {};
class DerivedBaseOne : public Base {};
class DerivedBaseTwo : public Base {};
class Derived : public DerivedBaseTwo, public DerivedBaseOne 
{};

//somewhere in the code, is Base() called two times here?
Derived * foo = new Derived();

Base()构造函数是否被调用了两次?构造函数是按什么顺序调用的呢?首先是基地?还是先用DerivedBaseOne()DerivedBaseTwo()

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-14 01:21:58

按照您编写的方式,Derived有两个不同于的Base类型的子对象,每个子对象都从各自的DerivedBaseXXX构造函数中调用它们自己的构造函数,它是DerivedBaseXXX的子对象。调用的顺序遵循声明的顺序。

相反,如果声明DerivedBaseXXX : virtual public Base,那么只有一个 Base子对象,并且它的构造函数是从派生最多的对象中调用的,即从Derived对象中调用。

(更详细地解释:一个(可能是单继承的)类是通过首先1)调用基类的构造函数,然后2)按声明的顺序调用所有成员对象的构造函数,最后3)执行构造函数主体来构造的。这是递归应用的,对于多重继承,您只需按照声明继承的顺序调用基类的所有构造函数来替换(1)。只有虚拟继承才会在这里增加一层真正的额外复杂性。)

票数 14
EN

Stack Overflow用户

发布于 2011-09-14 01:20:16

继承层次结构的构造函数调用顺序为:

Base()  
DerivedBaseTwo()  
Base()
DerivedBaseOne()  
Derived()

顺序确实是定义良好的,并且取决于您提到基类的派生的顺序以及在类中为成员声明成员的顺序。(请参阅下面的C++标准中的参考。)

是否会调用Base()构造函数两次?

是的

Base()类构造函数在这里被调用了两次,因为有两个类DerivedBaseTwo()DerivedBaseOne()派生自它,所以基类构造函数被调用一次。您的Derived类有两个不同的Base子对象,它们通过多个路径(一个通过DerivedBaseOne(),另一个通过DerivedBaseTwo())。

具有多重继承的类的层次结构是不寻常的,这会导致一个称为的问题。为了避免这个问题,C++引入了的概念。

参考资料:

C++03标准: 12.6.2/5,初始化库和成员

初始化应按以下顺序进行:

-首先,并且仅对于下面描述的最多派生类的构造函数,虚拟基类应该按照它们在基类的有向无循环图的深度优先从左向右遍历时出现的顺序进行初始化,其中“从左到右”是基类名称在派生类基说明符列表中的出现顺序。

-然后,直接基类应该按照它们在base-specifier-list中出现的声明顺序进行初始化(不管mem-initializers的顺序如何)。

-然后,应该按照类定义中声明的顺序对非静态数据成员进行初始化(同样,不管mem-initializers的顺序如何)。

-最后,执行构造函数的主体。

票数 20
EN

Stack Overflow用户

发布于 2011-09-14 01:21:58

答案是:http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.14

要执行的第一个构造函数是层次结构中任何位置的虚拟基类。它们按照它们在基类图形的深度优先从左向右遍历中出现的顺序执行,其中从左到右是指基类名称的出现顺序。

因为您的多重继承声明首先列出了DerivedBaseTwo,所以它的构造顺序将在DerivedBaseOne之前执行。

因此,在您的Derived类中,首先创建DerivedBaseTwo及其链,即:

1- Base,然后是DerivedBaseTwo

然后是DerivedBaseOne和它的链:

2- Base,然后是DerivedBaseOne

然后:

3- Derived是在创建其他所有内容之后创建的。

此外,对于多重继承,请注意Diamond Inheritance Problem

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

https://stackoverflow.com/questions/7405839

复制
相关文章

相似问题

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