注册 登录
编程论坛 C++教室

[讨论]关于虚拟的讨论,大家都来聊聊自己的见解。

wfpb 发布于 2007-05-29 15:15, 523 次点击
#include "stdafx.h"
class A
{
public:
virtual void Draw()=0;
virtual void Eat()=0;
};
class B
{
public:
virtual void Eat()=0;
virtual void Draw()=0;
};
class C:public A,public B
{
public:
virtual void Draw(){printf("Draw\n");}
virtual void Eat(){printf("Eat\n");}
};
int main(int argc, char* argv[])
{
C*pc=new C;
A*pa=(A*)pc;
B*pb=(B*)pc;
pa->Draw();
pb->Eat();
pb=(B*)pa;
pb->Eat();
pa=(A*)(B*)(C*)pa;
pa->Draw();
return 0;
}
输出:
Draw
Eat
Draw
Eat
根据多继承虚拟类,派生类中有多个vtbl指针,所以将派生类指针转换成基类时,如果只是转换成第一个继承的基类,那么指针没有偏移,因为都指向类的内存快的开始处,而转换成第二个基类时,将会发生偏移.在调用虚拟函数时,似乎是根据虚拟函数在基类中的索引顺序来调用。比如是A类指针调用Draw就是调用虚表第一个函数,B类就是调用第二个函数。所以如果将一个B类指针转换成A类指针,然后调用A类的Draw函数,其实就是调用B类的Eat函数。
7 回复
#2
zinking2007-05-29 22:27

对于VTBL的原理的探究固然很好,但是从实用的角度出发,是不是这段代码没有意义呢?

这段代码能够给我们实际的开发带来什么好处吗?能带来一种新的设计模式吗?我认为多态的好处是这样
pa->draw()
pa->eat()
它的集成类能够通过多态实现不同的操作

而不是无意义的进行指针之间的无意义的强制转化

当然斑竹大人你纯粹探讨这么个编译原理的东西,也未尝不可

聊且一辨

#3
aipb20072007-05-29 23:08

mark下!
#4
wfpb2007-05-29 23:54
to zinking:
由于最近看COM技术内幕,这才了解了一点vtbl的东西,以前都没怎么看过,所以就想了解一下vtbl的其他特质(以前只知道单继承时的vtbl的作用)。比如这个转换偏移就是今天刚刚才知道的,所以想和大家探讨一下。对于上面的那段代码:的确是没用的垃圾代码

不过只是为了验证vtbl和偏移这两个东东的测试代码。。。
#5
轮廓2007-05-30 16:14
http://kongfuziandlife.blogspot.com

里面的东西有些确有见解,呵呵,谢谢zinking分享
#6
zinking2007-05-30 19:43


多继承已经被废弃了,可以这么说!现在新出来的语言如JAVA,C#都不支持多继承,

当然了解原理是很好的,想我这样只注重实际的有的时候真的会被原理所困
#7
wfpb2007-06-17 20:53
多继承为什么会废气啊?
组件编程时不是要继承多个接口吗?
难道每个组件只能实现一个接口,然后只能用一个组件来聚合所有接口吗?
1