1、reintrodure本身没什么东西,只是不让编译器产生一个警告(Warning)。
2、代码正确,但是编译器会产生一个警告。
3、代码有些问题,基类需要加上virtual或者dynamic的关键字。这是多态的概念。
2、代码正确,但是编译器会产生一个警告。
3、代码有些问题,基类需要加上virtual或者dynamic的关键字。这是多态的概念。
解决方案 »
- 用C++ Builder更新数据库内容,提示ADOQuery1:missing SQL property
- FileStream怎么样可以多次读取同一文件?
- 关于dbgrid的问题
- 如何将十六进制的字符转成unicode???
- Drate(小虫)请来接1000分__8) 原贴:http://expert.csdn.net/Expert/topic/2227/2227167.xml?temp=.3559534
- 哪里有DELPHI6的安装盘下载,大家帮忙推荐一下,多谢
- 三层结构下,clientdataset中用applyupdate更新数据库时提示Record not found or changed by another user?
- 100分求:Delphi的打印预览源码
- 有没人会啊~~~~~~~~~~~~~
- 怎么回事,怎么回事???谁能解决》》》。
- 怎样用delphi构造一个防火墙!!??
- 求高手帮分析记录的存放格式!
type
tsomebase=class
procedure cooper;
end;
tsomeclass=class(tsomebase)
procedure cooper;override;
end;
是这样,但3和2 有么区别呢?
在使用是。我想知道,3是覆盖了
2是,隐藏父类的方法。
可是区别呢??
如果是override,基类可能是这样:
tsomebase=class
procedure cooper; virtual;
end;1和2都会隐藏父类的方法,但是用1,编译器不产生警告,而2产生。
3则既可以使用父类的方法,也可以不使用父类的方法。完全根据需要,用inherited关键字来实现。
默认下,类方法是静态的。即各类对象引用自己所定义的方法。
另,如果父类定义的方法是虚拟的(virtual/dynamic,abstract的),但如果子类定义中不加override,则还是覆盖了父类的定义。
请大虾,在仔细说好吗??
小弟,今天一定要弄明白
完全根据需要,用inherited关键字来实现。 //
详细讲好吗??
2、如果非要引进父类的方法,可以随时用inherited。
我认为是,最起码,程序上体现出来了,
type
tsomebase=class
procedure cooper;
end;
tsomeclass=class(tsomebase)
procedure cooper;reintrodure;
end;
tsomeclass1=class(tsomebase)
procedure cooper;reintrodure;
end;
各位大虾,对不起。
但是上面的程序
我认为实现了,多态。
我认为多态是只同样的名字的方法,
在不同的对象中,有不同的操作。
我想是这样。
那为什么,
上面的程序没有实现呢?
type
TA = class
procedure Hello; virtual;
end;
TB = class
procedure Hello; override;
end;{ TA }procedure TA.Hello;
begin
ShowMessage('Hello');
end;{ TB }procedure TB.Hello;
begin
ShowMessage('World');
end;现在有这么一段代码:
var
a: TA;
begin
a := TB.Create;
a.Hello;
end;问a.Hello显示的是什么内容?
如果你去掉virtual和override,又显示什么内容?
procedure Hello; override;
end;
因为在多态情况下,尽管a是TA类型,但是a中对象是TB,所以调用的一定是TB.Hello。这就是多态的魅力所在。
我在想想有什么要说的,不过我对
DELPHI的多态还是不太明白。
所以恳请NICROSOFT写篇文章。
当然,如果有人要讨论的当然欢迎。
我现在还没有头绪,只能
写程序,试
如果改成
TB(a).hello呢
那就是 WORLD了
是实现多态了吗??
我不知道,但挺有意思的,我还没有弄懂
是这样的
vcl中的TObject类存在一指向需方法表的指针VPTR,这是编译器默认加上的,可以证明
如
TA = class
private
AA: Integer;
end;procedure TForm1.Button1Click(Sender: TObject);
var
t: TA;
begin
t := TA.Create;
ShowMessage(IntToStr(t.InstanceSize));
t.Free;
end;
这里输出为8,如去掉AA:Integer的声明为4,这就证明编译器隐含为我们加了一个VPTR,也就是指向虚方法表的指针,在以上一个为例
我这么写
Interface TA = class
private
AA: Integer;
public
procedure Show; virtual;
procedure Show1; virtual;
end; TB = class(TA)
procedure Show; override;
procedure Show1; override;
end;implementationprocedure TA.Show;
begin
ShowMessage('TA Show');
end;procedure TA.Show1;
begin
ShowMessage('TA Show1');
end;procedure TB.Show;
begin
ShowMessage('TB Show');
end;procedure TB.Show1;
begin
ShowMessage('TB Show1');
end;//用个简单的汇编函数,其中EAX即为指向TA的实例的指针,[EAX]即为它的内容其实也就是VPTR
//CALL DWORD PTR[EAX]就是调用这个虚方法表的第一项,也就是虚拟方法Show的地址
procedure ShowInformation(AObject: TA);
asm
MOV EAX, [EAX]
CALL DWORD PTR [EAX]
end;procedure TForm1.Button1Click(Sender: TObject);
var
tmp: TA;
A: TA;
B: TB;
begin
A := TA.Create;
B := TB.Create;
tmp := A;
ShowInformation(tmp); tmp := B;
ShowInformation(tmp);
A.Free;
B.Free;
end;输出为'TA SHOW','TB Show'这很明显当tmp := A 时,因为tmp指向了A的内容,当调用Show时通过VPTR调用的是A的虚拟方法表中的第一项的内容,当tmp := B时,tmp指向B, 当调用Show时通过VPTR调用的是B的虚拟方法表中的第一项的内容,而当Show不是虚拟方法时,因为c++保持了类型信息,这是根据它的类型来调用,所以即使tmp := B, 调用的还是TA的Show,而Show为虚拟的话,通过VPTR来调用,从而也实现了多态,但是每声明了一个类,每个类都在内存中维持了一份虚拟方法表,这样当有多个派生类时则很浪费内存,好橡叫类膨胀吧,我也不太懂,而delphi中又有了dynamic方法,这其实在
VPTR的偏移量为vmtDynamicTable处有一指向多态方法表的指针,当声名为dynamic方法时,系统
就把此方法放进该类的多态方法表中,当调用时首先从该类得多态方法表中查找,如找不到,则根据该类的VPTR的偏移量vmtParent处可找到其父类的多态方法表,在查找。所以当一个类声明了很多虚方法,如声明为virtual,有很多子类继承并不重用的话,将很浪费内存,因为每一个子类都要建一虚拟方法表并存储各虚拟方法的地址,而声明为dynamic的话,则子
类重用的方法指针才放入多态方法表中,这也节省了内存,但同时也牺牲了调用的速度好了,就说这些把,写得乱七把糟的,我自己其实也不太懂,呵呵
liu ge ming ,yong de zhao d shi hou
小弟认为,是否可以这样理解呢?
虚拟方法的访问,是要根据,对象(引用)的实际位置,
决定的。和对象的类型没有关系(前提是有继承关系)
而静态方法的访问,是根据对象的类型,而不是
实际位置。以上观点,不知道各位大虾,怎么看。
希望,大虾指点。谢谢
不好意思,我也是一知半解,建议看一看
<<深入探索C++对象模型>>
我一直也没有时间看
在内存的布局好象不同,
可以理解为相同吗??
我只懂一点C++
大家见笑了
太感谢你了,希望以后多交流,
我的QQ 是 64632160
还有一个忘了,