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();
};
根据此article,类d
的对象D
的内存布局如下:
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
的对象怎么样?在课程D1
中,成员f1
和f2
都声明为virtual
!
答案 0 :(得分:3)
在virtual
中使用D1
是多余的。
来自C ++ 11,§10.3¶2:
如果在类
vf
和类Base
中声明虚拟成员函数Derived
,直接或间接地从Base
派生,则成员函数{{1与vf
声明同名,参数类型列表(8.3.5),cv-qualification和ref-qualifier(或不存在相同),然后Base::vf
也是虚拟的(无论是否声明)并覆盖 111Derived::vf
。111)具有相同名称但不同参数列表(第13条)作为虚函数的函数不一定是虚拟的,也不会覆盖。在覆盖函数的声明中使用
Base::vf
说明符是合法的但是冗余的(具有空语义)。在确定覆盖时不考虑访问控制(第11条)。
因此,virtual
和D
的内存布局(问题似乎就是这个问题)是相同的。显然,不同的类型将有不同的虚拟表。
答案 1 :(得分:1)
f1()
和f2()
也是D
中的虚拟。如果某个函数声明为 virtual ,则它在任何继承的类中仍然是虚拟。
因此,类D
和D1
内部几乎没有区别(但显然是不同类型),但它们都提供了f1
和f2
的实现,它们的虚拟表会有所不同,因为D
的虚拟表将指向D
的实现,而D1
则相同。
vtable for D:
f1: D::f1
f2: D::f2
vtavle for D1:
f1: D1::f1
f2: D1::f2