31

I'm trying to understand the affect of inheritance order in C++.. I looked online, but I couldn't find a clear and sufficient answer...

So, for the sake of the question, assume there are 2 classes: class B and class C.

Now, define:

class A1 : public B, public C{ ... };
class A2 : public C, public B{ ... };

What is the difference between A1 and A2?

Thanks a lot!

TCS
  • 5,790
  • 5
  • 54
  • 86
  • Intersting question. I would like to know the answer. I found this link - http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm , which claims, "The order of derivation is relevant only to determine the order of default initialization by constructors and cleanup by destructors." Maybe someone can confirm this? – OldProgrammer Jun 26 '13 at 19:40

2 Answers2

23

The C++11 Standard says (§10.1) [class.mi]:

The order of derivation is not significant except as specified by the semantics of initialization by constructor (12.6.2), cleanup (12.4), and storage layout (9.2, 11.1).

The three referenced paragraphs reveal that

  • Constructors are called in the order you write them down (first base class in the list is constructed first) (§12.6.2.10). Different rules apply to virtual base classes which are always constructed from the most-derived class before any direct base classes.
  • Destructors are called in the inverse order of construction (first base class in the list is destructed last)
  • Storage layout is unspecified. You must not make any assumptions about the class layout in memory. The only exception are so called standard-layout classes (§9), which is basically a C-style struct. But since those are not allowed to have more than one class with non-static members in the class hierarchy, the question does not really apply here.

Note that the memory layout can be important. For example, if an external library makes naive C-style casts that assume that the part of the object it's interested in is at the beginning, it can lead to run time errors that are hard to debug.

ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
  • 3
    I don't "consider" anything. "implementation defined" was defined in the C89 ANSI standard, and the same definition is used in C++. Only things that the standard describe as "implementation defined" are considered "implementation defined": **if something is "implementation defined", then the implementation is required to document it**. The implementation is of course allowed to also document anything it wants. It may describe the order of evaluation of `operator +` arguments, but that is not required. It may document the layout of the vtable, but that is not required. – curiousguy Jul 07 '13 at 23:43
  • "_it is the implement's responsibility to determine the layout_" the implementation must also choose one order of evaluation out of two possibilities every time you write `f(g(),h())`, but the way it chooses one is rarely described. The implementation is responsible for many things which are not documented except in the source code. – curiousguy Jul 07 '13 at 23:45
  • @curiousguy Which is exactly what the answer was trying to express: _You must not make any assumptions about the class layout_. The term _implementation-defined_ here suffers from slightly different meanings in ISO-speak and in colloquial speech (which is the case for many terms used in the standard). To avoid this source of confusion I changed the wording of the answer. We could have done this in a lot less posts if your original post already contained the information from your second-to-last one. Thanks for staying with me though. – ComicSansMS Jul 08 '13 at 07:07
  • I am sorry, but did not realize that you were not using "implementation defined" in the C++ std sense, until late in our exchange. – curiousguy Jul 08 '13 at 10:42
  • The original description *"Storage layout is implementation-defined."*, before the editing, is good I think. Maybe "unspecified in the language standard(it's implementation-defined)" can be better, too wordy though :) – starriet Sep 04 '22 at 02:32
17

The order of derivation is relevant only to determine the order of default initialization by constructors and cleanup by destructors.

The order of derivation is not significant except as specified by the semantics of initialization by constructor (12.6.2), cleanup (12.4), and storage layout (9.2, 11.1). — end note ]" (§10.1/2)

From IBM's C++ documentation: Multiple inheritance

Community
  • 1
  • 1
Haagenti
  • 7,974
  • 5
  • 38
  • 52
  • 1
    Your answer would be better if you were to put the quote directly instead of having the link. – user123 Jun 26 '13 at 19:38
  • 1
    Quote is there directly? Or am I missing something? – Haagenti Jun 26 '13 at 19:39
  • True, but raw links are tacky :/ – user123 Jun 26 '13 at 19:42
  • Yes true. Not sure how to style it. Pretty new here but I will try something – Haagenti Jun 26 '13 at 19:43
  • Thank you Mat. Will you this for future references – Haagenti Jun 26 '13 at 19:44
  • 5
    Glad to help. Here's a quote from the standard: "[ Note: The order of derivation is not significant except as specified by the semantics of initialization by constructor (12.6.2), cleanup (12.4), and storage layout (9.2, 11.1). — end note ]" (§10.1/2) - the IBM docs miss the part about layout. (You can edit that into your post too if you wish.) – Mat Jun 26 '13 at 19:46
  • Info about memory layout for multiple and virtual inheritance: http://www.phpcompiler.org/articles/virtualinheritance.html – TCS Jun 27 '13 at 06:02
  • @Mat In C++, the layout of such class objects is unspecified. – curiousguy Jul 03 '13 at 23:10