虚函数的结构从简单到复杂都有各种各样的案例。什么因素决定了它需要多少额外的内存?例如
class A {virtual void F() {} };
class B : public A {virtual void F() {} };
与没有虚函数的类相比,A 和 B 需要多少内存?另一个有 2 个虚函数的例子,
class A {virtual void F() {} virtual void G() {} };
class B : public A {virtual void F() {} virtual void G() {} };
和示例 3
class A {virtual void F() {}; virtual void G() {} };
class B : public A {virtual void F() {} };
[---------------添加更多有趣的问题------]
每个虚拟方法都有一个虚拟方法表吗?如果是这样,我认为对于具有多个虚拟方法的类(不是对象,对吗?我认为 VPTR 是静态的。)需要多个 VPTR,每个用于一个虚拟方法。对?
是否可以为所有虚拟方法只构建一个表并在一个类中只放置一个 VPTR?
而且我觉得虚函数的调用速度应该比手动ifs要快,因为使用的是直接的VPTR。对?
[ - - - - - - - - 一个测试 - - - - - - - - ]
我做了一个测试,并用 VS2010 和 intel c++ 编译器展示了我的结果。
struct A
{
static int s_i;
int i;
virtual void F() {i+=1;}
virtual void G() {i+=2;}
};
struct B
: public A
{
int j;
virtual void F() {i+=3;}
virtual void G() {i+=4;}
virtual void H() {i+=5;}
};
struct C
: public B
{
virtual void F() {i+=6;}
virtual void H() {i+=7;}
};
TEST(MemoryForVirtualMethod)
{
CHECK_EQUAL(sizeof(A), 8);
CHECK_EQUAL(sizeof(B), 12);
CHECK_EQUAL(sizeof(C), 12);
}
从结果来看,我的结论是
(1) 对于每个具有虚函数的对象,添加一个(隐藏指针)VPTR。
(2)对每个类,为该类的所有虚方法建立一个虚方法表。
(3) 将VPTR放在object中是为了实现动态调度,因为引用的类可能不是动态类。
(4)实现调用效率高(比手动ifs快)但牺牲了一些内存。
非常感谢!