是这样的, 因为C++的多重继承, 就VC的实现来看
eg. class C : public A, public B
那么C的数据区 由 A的数据区 后紧跟着B的数据区 组成 (包括 虚函数表)
上述ppv 前后差的4byte 就是 IUknown(IX) 的虚函数表指针大小
eg. class C : public A, public B
那么C的数据区 由 A的数据区 后紧跟着B的数据区 组成 (包括 虚函数表)
上述ppv 前后差的4byte 就是 IUknown(IX) 的虚函数表指针大小
楼上说的好。不多将了
http://www.csdn.net/expert/Topic/49354.shtm回复人:fengye(2000-12-19 12:21:00) 得5分
This article in MSDN may help
Technical Articles/Visual Tools/Visual C++ 6.0/C++: Under the Hood 回复人:zhangzhonghua(2000-12-19 19:31:00) 得0分
fengye推荐的文章的作者是Microsoft C++编译器的开发人员之一,他的文章看来是最权威的了。
谢谢fengye的指点。我以前怎么没发现这篇文章呢,浪费了这么多时间?哎,MSDN真是个宝库,没看到的东西太多了!
这是不是多重继承的一个特性啊??
LOOK : for example:class C : public A, public BVC实现 class C 的某个实例的内存表示: class C 某个实例所占内存:
||
\/
+--------------+ <--------- (IUnknown*)this
| 从A继承下来的 |
| 数据区(当然 |
| 包括A的vtable)|
+--------------+ <-------- (INondelegatingUnknown*)this
| 从B继承下来的 |
| 数据区(当然 |
| 包括B的vtable)|
+--------------+上例中 A 就是 IX, B 就是 INondelegatingUnknown
由于 IX 中并没有加入自己的数据属性 , 所以 (IUnknown*)this
的地址 == (IX*)this
非自然多型。
class A
{
public: virtual void SayHello() { cout << "I'm A" << endl;}
}
class B
{
public: virtual void SayHello() { cout << "I'm B" << endl;}
}
class C : public A, public B
{
}main()
{
C aC;
A *pA;
B *pB;
pA = &aC;
pA->SayHello(); // 编译器转化为 A::SayHello(this) 实际调用 this->vtbl[0]
pB = &aC;
pB->SayHello(); // 编译器转化为 B::SayHello(this) 实际调用 this->vtbl[0]
}
如果pB = &aC;不调整this指针,pB->SayHello();会输出什么?
对virtual函数的调用,是先找到this指针地址,接着顺着this指针找到vtbl,而virtual函数入口就在vtbl里。如果this指针不调整,出错难免。
你希望 pA->SayHello(); 输出"I'm A"
希望 pB->SayHello(); 输出"I'm B"如果this指针不调整,做不到。