Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
331 views
in Technique[技术] by (71.8m points)

c++ - Are multiple-inherited constructors called multiple times?

Are multiple-inherited constructors called multiple times? And in what order are constructors called? Does this depend on the order in the inheritance list?

Here is an example (it's only for making the situation clear, no real-life example).

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();

Is the Base() constructor called twice? And in what order are the constructors called? Base first? Or DerivedBaseOne() or DerivedBaseTwo() first?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The order of constructor calls for your inheritance hierarchy will be:

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

The order is indeed well-defined and depends on the order in which you mention the derivation for base classes and the order in which you declare members in the class for members. (See the reference from the C++ Standard below.)

Does the Base() constructor get called twice?
YES

The Base() class constructor gets called here twice, because two classes DerivedBaseTwo() and DerivedBaseOne() derive from it, so the base class constructor gets called once for each of them. Your Derived class has two distinct Base subobjects through multiple paths (one through DerivedBaseOne() and the other though DerivedBaseTwo()).

The hierarchy of classes you have with multiple inheritance is unusual and it leads to a problem called the Diamond Shaped Inheritance Problem. To avoid this problem C++ introduces the concept of Virtual base class.


Reference:

C++03 Standard: 12.6.2/5, Initializing bases and members

Initialization shall proceed in the following order:

— First, and only for the constructor of the most derived class as described below, virtual base classes shall be initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base class names in the derived class base-specifier-list.

— Then, direct base classes shall be initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).

— Then, nonstatic data members shall be initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

— Finally, the body of the constructor is executed.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...