• 全部
  • 语言基础/算法/系统设计
  • 数据库相关
  • 图形处理/多媒体
  • 网络通信/分布式开发
  • VCL组件开发及应用
  • Windows SDK/API
  • 问答

讨论一下,virtual与dynamic的区别

Tompage 2001-08-18 03:00:04
...全文
148 点赞 收藏 20
写回复
20 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Tompage 2001-08-25
真的没有别的意见了吗???踊跃发言阿!
回复
Tompage 2001-08-23
up一下,再看看大家的意见
回复
Tompage 2001-08-22
就我个人看法,当一个子类从父类继承过来时,应该对父类没有任何变化,但是父类又如何得到子类的VMT呢?
回复
csdn72 2001-08-22
gz
回复
Tompage 2001-08-22
但是VMT是如何生成的,调用时又是如何访问VMT的呢,DMT又是怎样的呢?
回复
Scarlette 2001-08-22
父类是不可能得到子类的VMT的。因为VMT的查找方式是从子类向父类逆推的。
回复
Tompage 2001-08-20
再up一下
回复
Nicrosoft 2001-08-20
dynamic在一定程度上,阻止了虚函数表由于类层次扩展而变得非常庞大(类爆炸?)
回复
Tompage 2001-08-19
怎么没人跟贴了?UP一下
回复
xzm2000 2001-08-19
关注起来
回复
trainbox 2001-08-19
gz
回复
Tompage 2001-08-19
但是,对动态方法的调用过程还是不太理解
比如,从某个类Ta派生一个子类Tb,重载了动态方法c,那么这时候类Tb和Ta的DMT表是怎样的,调用过程又是怎样的呢?
如果是虚拟方法又如何呢??
回复
Tompage 2001-08-19
多谢各位大虾的指点,小弟明白了!
回复
qqcxg 2001-08-18
动态方法和虚方法在功能上类同,差别只在于Delphi对于它们内部实现方式不同,
对于虚方法,Delphi会创建一个虚拟方法表(VirtualMethodTable)用以加速索引,这就造成了消耗内存资源多一点;而动态方法相比较而言,由于没有VMT支持,速度稍慢,但更节约资源.
如果你在类中要定义许多方法,而这些方法又不是都经常被调用,则应将它们定义为动态方法,事实上Borland便是这么作的!!
回复
dancemaple 2001-08-18
在代码中调用一个虚拟方法时,编译器并不知道它的地址。因此,编译器通过建立虚拟方法表(VMT)来查找在运行时的函数地址。所以,虚拟方法比动态方法用的内存要多,但它执行得比较快。
对于动态方法,编译器为每一个动态方法指定一个独一无二的数字,用这个数字和动态方法的地址构造一个动态方法表(DMT),在DMT表中仅有它声明的动态方法,并且这个方法需要祖先的DMT表来访问它其余的动态方法。所以,动态方法比虚拟方法用的内存要少,但执行要慢,因为有可能要到祖先类的DMT表中查找动态方法。
以上说明摘抄自《D5 开发人员指南》
另外,这里说的重载不合适。重载是指关键字overload,而orerride一般翻译成“覆盖”
回复
zzutlink 2001-08-18
葡萄!你太夸张了吧?呵呵
回复
Tompage 2001-08-18
除了速度的差别外,应该还有其他区别吧?
回复
Mickey_Chue 2001-08-18
DELPHI中方法的类型及其覆盖、重载

Mickey_Chue(菩提葡萄)

1、静态方法是方法的缺省类型,对它就像对通常的过程和函数那样调用,编译器知道这些方法的地址,所以调用一个静态方法时它能把运行信息静态地链接进可执行文件,所以,静态方法速度最快,但它们却不能被覆盖来支持多态性。

2、虚拟方法和静态方法的调用方式相同。由于虚拟方法能被覆盖,在代码中调用一个指定的虚拟方法时编译器并不知道它的地址,因此,编译器通过建立虚拟方法表(VMT)来查找在运行时的函数地址。所有的虚拟方法在运行时通过VMT来高度,一个对象的VMT表中除了自己定义的虚拟方法外,还有它的祚的所有的虚拟方法,因此虚拟方法比动态方法用的内存要多,但它执行得比较快。

3、动态方法跟虚拟方法基本相似,只是它们的高度系统不同。编译器为每一个动态方法指定一个独一无二的数字,用这个数字和动态方法的地址构造一个动态方法表(DMT)。不像VMT表,在DMT表中仅有它声明的动态方法,并且这个方法需要祖先的DMT表来访问它蓁的动态方法。正因为这样动态方法比虚拟方法用的内存要少,但执行起来罗慢,因为有可能要到祚对象的DMT中查找动态法。

4、OP通过覆盖使一方法在不同的派生类间表现出不同的行为。OP中能被覆盖的方法是在声明时被标识为virtual或dynamic的方法。为了覆盖一个方法,在派生类的声明中用override代替virtual或dynamic。用了override后,编译器就会用新的方法替换VMT中原先的方法,而原先的方法也还存在,而如果用override再次声明一个静态方法,则是真正的覆盖,是用新的方法完全替换在祖先类中的同明方法。

5、方法重载的意义:比如说,你要写一个求两数商的函数(当然只是个比喻),你希望这个函数可以处理所有的数值类型,但PASCAL的运算对类型实行严格检查,你不得不用不同的程序来运算不同类型的数值,这样你就必须为每一种类型写一个同样功能的函数,并使用不同的函数名,坏处我想你是知道的。而重载却可以解决这个问题,同样的函数名,编译器可以用不同的形参类型决定调用哪个函数。
回复
zzutlink 2001-08-18
virtual是虚拟的,通过VMT(VIRTUAL METHOD TABLE,虚拟方法表),执行速度快

dynamic是动态的,通过DMT(DYNAMIC METHOD TABLE,动态方法表),执行速度相对慢

两者均可重载!
回复
Tompage 2001-08-18
如何重载??
回复
发帖
Delphi
创建于2007-08-02

4870

社区成员

Delphi 开发及应用
申请成为版主
帖子事件
创建了帖子
2001-08-18 03:00
社区公告
暂无公告