C++ C+中多继承对象的内存布局+;

C++ C+中多继承对象的内存布局+;,c++,compiler-construction,multiple-inheritance,C++,Compiler Construction,Multiple Inheritance,基于此,类d的对象d的内存布局如下: class B1 { virtual void f1(); int int_in_b1; }; class B2 { virtual void f2(); int int_in_b2; }; class D: B1, B2 { int int_in_d; void f1(); void f2(); }; class D1: B1, B2 { int int_in_d; virtual v

基于此,类
d
的对象
d
的内存布局如下:

class B1 {
    virtual void f1();
    int int_in_b1;
};
class B2 {
    virtual void f2();
    int int_in_b2;
};
class D: B1, B2 {
    int int_in_d;
    void f1();
    void f2();
};
class D1: B1, B2 {
    int int_in_d;
    virtual void f1();
    virtual void f2();
};
类为
D1
的对象如何?在类
D1
中,成员
f1
f2
都声明为
virtual

f1()
f2()
D
中也是虚拟的。如果函数被声明为虚拟函数,则它在继承的任何类中都保持虚拟

因此,类
D
D1
内部几乎没有区别(但显然是不同的类型),但它们都给出了
f1
f2
的实现,它们的虚拟表将有所不同,因为
D
的虚拟表将指向
D
的实现,对于
D1
,也是如此

d:
  +0: pointer to virtual method table of D (for B1)
  +4: value of int_in_b1
  +8: pointer to virtual method table of D (for B2)
 +12: value of int_in_b2
 +16: value of int_in_d

virtual method table of D (for B1):
  +0: D::f1()  // B1::f1() is overridden by D::f1()

virtual method table of D (for B2):
  +0: D::f2()   // B2::f2() is overridden by D::f2()

D1
中,使用
virtual
是多余的

d:
  +0: pointer to virtual method table of D (for B1)
  +4: value of int_in_b1
  +8: pointer to virtual method table of D (for B2)
 +12: value of int_in_b2
 +16: value of int_in_d

virtual method table of D (for B1):
  +0: D::f1()  // B1::f1() is overridden by D::f1()

virtual method table of D (for B2):
  +0: D::f2()   // B2::f2() is overridden by D::f2()
来自C++11,§10.3¨2:

如果虚拟成员函数
vf
在类
Base
和类
Derived
中声明,直接或间接从
Base
派生,则成员函数
vf
具有相同的名称、参数类型列表(8.3.5)、cv限定符和ref限定符(或没有相同的)当声明
Base::vf
时,那么
Derived::vf
也是虚拟的(无论是否声明)
并且它覆盖111
Base::vf


111)与虚函数同名但参数列表不同的函数(第13条)不一定是虚函数,也不重写。在声明重写函数时使用
virtual
说明符是合法的,但是多余的(语义为空)。在确定覆盖时不考虑访问控制(第11条)


因此,
D
D1
的内存布局(这似乎是问题所在)是相同的。显然,不同的类型将有不同的虚拟表。

动态多态性的实现是实现细节,而不是C++本身的事实。因此,请指定您正在谈论的ABI。可能重复@jxh,拼写错误。应该是B1和B2为什么B1::f1()在D中没有被重写?@newbie:wikipedia文章中的剪切粘贴错误,这说明了如果不重写会发生什么。我修正了这个问题。但是虚拟方法表的内容肯定会有所不同…@JonasWielicki,这正是我想问的。虚拟方法表有什么不同?根据您的更新,它们似乎是相同的。@Daniel
D
D1
中的每一个都为
f1
f2
提供了各自的实现。虚拟表将分别指向
D
D1
中的实现。@FihopZz不,它们不是。