2013-06-26 114 views
17

我想了解继承顺序在C++中的影响..我在网上查找,但我找不到明确而充分的答案...C++多重继承顺序

因此,为了的问题,假设有2类:B类和C类。

现在,定义:

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

是什么A1和A2之间的差异?

非常感谢!

+0

Intersting问题。我想知道答案。我发现这个链接 - http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm,它声称,“推导的顺序仅与确定构造函数的默认初始化顺序和通过析构函数清理的顺序有关。“也许有人可以证实这一点? – OldProgrammer

回答

11

推导顺序仅与确定构造函数的默认初始化顺序和通过析构函数清理有关。

除了由构造函数(12.6.2),清理(12.4)和存储布局(9.2,11.1)进行初始化的语义指定外,派生顺序并不重要。 - 注完]”(§10.1/ 2)

从IBM的C++文档:Multiple inheritance

+1

如果您直接放置报价而不是链接,则您的答案会更好。 –

+1

报价是直接存在吗?或者我错过了什么? – Haagenti

+0

确实如此,但原始链接很俗气:/ –

7

的C++ 11标准说(§10.1):

推导的顺序是不显著除非由构造(12.6.2),清理(12.4), 和存储布局(9.2,11.1)中指定由初始化 语义。

个三个引用段落显示,

  • 构造函数的调用你写下来(列表中的第一个基类构造第一)(§12.6.2.10)的顺序。不同的规则适用于在任何直接基类之前总是由派生最多的类构造的虚拟基类。
  • 破坏程序按构造的反向顺序调用(列表中的第一个基类最后被破坏)
  • 存储布局未指定。你不能对内存中的类布局做任何假设。唯一的例外是所谓的标准布局类(§9),它基本上是C风格的结构。但是由于这些类不允许在类层次结构中拥有多个非静态成员的类,所以这个问题在这里并不适用。

请注意,内存布局可能很重要。例如,如果一个外部库做出天真的C风格转换,假设它感兴趣的对象的部分在开头,它可能会导致难以调试的运行时错误。

+3

我不“考虑”任何东西。 “定义的实现”是在C89 ANSI标准中定义的,并且在C++中使用了相同的定义。只有标准描述为“实现定义”的东西才被认为是“实现定义的”:**如果某些东西是“实现定义的”,那么需要实现来记录它。这个实现当然也允许记录任何想要的东西。它可以描述'operator +'参数的评估顺序,但这不是必需的。它可以记录vtable的布局,但这不是必需的。 – curiousguy

+0

“_it是实现者确定layout_的责任”每次你写'f(g(),h())'时,实现也必须从两种可能性中选择一种评估顺序,但它选择的方式很少描述。该实现负责许多除源代码外没有记录的内容。 – curiousguy

+0

@curiousguy答案正是想要表达的是:_你不能对班级布局做任何假设。术语_implementation-defined_在ISO语言和口语语言中有着稍微不同的含义(这是标准中使用的许多术语的情况)。为了避免这种混淆,我改变了答案的措词。如果您的原始帖子已经包含您倒数第二的信息,我们可以在更少的帖子中完成此操作。谢谢你和我在一起。 – ComicSansMS