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
也是虚拟的(无论是否声明)并且它覆盖111Base::vf
111)与虚函数同名但参数列表不同的函数(第13条)不一定是虚函数,也不重写。在声明重写函数时使用
virtual
说明符是合法的,但是多余的(语义为空)。在确定覆盖时不考虑访问控制(第11条)
因此,
D
和D1
的内存布局(这似乎是问题所在)是相同的。显然,不同的类型将有不同的虚拟表。动态多态性的实现是实现细节,而不是C++本身的事实。因此,请指定您正在谈论的ABI。可能重复@jxh,拼写错误。应该是B1和B2为什么B1::f1()在D中没有被重写?@newbie:wikipedia文章中的剪切粘贴错误,这说明了如果不重写会发生什么。我修正了这个问题。但是虚拟方法表的内容肯定会有所不同…@JonasWielicki,这正是我想问的。虚拟方法表有什么不同?根据您的更新,它们似乎是相同的。@DanielD
和D1
中的每一个都为f1
和f2
提供了各自的实现。虚拟表将分别指向D
或D1
中的实现。@FihopZz不,它们不是。