最近十分颓废,为了改变这种状态,建议自己再一次去看基础。
还是多态中late_binding技术。大家都知道,编译器对virtual function的处理方式是通过vtable完成的。但我今天突然想知道 是否每个对象都要维护一张单独的vtable 还是共享使用同一个vtable呢?为次 写了一些测试代码:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
Base(){m_base = 10;};
~Base(){};
virtual void test(){ cout << " this is Base::test() " << endl; };
virtual void test_1(){ cout << " this is Base::test_1() " << endl; };
private:
int m_base;
};
class A : public Base
{
public:
A(){ m_A = 20;};
~A(){};
public:
virtual void test(){ cout << " this is A::test() " << endl; };
virtual void test_1(){ cout << " this is A::test_1() " << endl; };
private:
int m_A;
};
class B : public A
{
public:
B(){ m_B = 30; };
~B(){};
public:
virtual void test(){ cout << " this is B::test() " << endl; };
virtual void test_1(){ cout << " this is B::test_1() " << endl; };;
private:
int m_B;
};
int _tmain(int argc, _TCHAR* argv[])
{
Base *pBase = new A();
Base *pBase0 = new B();
Base *pBase1 = new B();
pBase->test();
pBase0->test();
pBase1->test();
return 0;
}
大家想必都已经知道了 对于含有virtual function的类 其对象的地址开始就是指向vtable的vptr 上例中的pBase pBase0 pBase1开始都是vptr的值。跟踪调试 在memory中(我的是32位机器) pBase开始四个字节的值: pBase地址:0x003D9F58 该地址处开始的四个字节:04 78 41 00(这四个字节就是vtable的地址) pBase0=0x003d9fa0 该地址开始处的四个字节:20 78 41 00 pBase1=0x003d64f0 该地址开始处的四个字节:20 78 41 00
可以发现什么?pBase0与pBase1 共享同一个vtable 因为二者是属于同一个类的两个对象 而pBase自己使用另外一个vtable
说明:每一个抽象类的派生都会维护自己的一个vtable(当然了) 这样的话 若类层次特别深 则其内存开销会非常大。