将一个子对象强制转化为它的父对象后,调用其父对象的Free方法能否将子对象正确释放?(50分)

  • 主题发起人 主题发起人 receyes
  • 开始时间 开始时间
R

receyes

Unregistered / Unconfirmed
GUEST, unregistred user!
例如有如下代码:
procedure Form1.test;
var
i: Integer
begin
i := Integer(Form2);//Form2已创建
TForm(i).Free;
end;

最后一句 TForm(i).Free 能否正确地释放了Form2?使用过程中我没有碰到什么问题,
感觉也应该没什么问题,但总是不放心。请各位老大多给点理论,多谢!


 
应该没问题,已经Free,因为Form2是从TForm继承,它们的释放过程是相同的。
 
绝对没问题!因为类型的强制转换并不能改变Free的入口,我以前写过一个程序,用一个基类数组存放各种派生类,
最后都调用Free方法,OK!
Delphi是不会让人钻这个空子的(VC也一样)。
 
绝对没问题!你可以从一个类继承一个新类,并重载Destroy方法,然后创建新类的一个实例,将该实例传给
其父类的一个变量,调用父类变量的Free方法,调试一下,你会看到先执行的是新类的Destroy。

这似乎就叫OOP的多态性吧,我对概念一向不清楚的。
 
不见得吧。
如果你的form1是这样定义的呢?
type form1=class(form)
private:
btn:TButton;
public:
constructor Creat(AOwner:tComponent);override;
....
constructor Form1.Create(AOwner:tComponent);override;
begin
inherited Create;
btn:=TButton.Create(this);
end;
呢?那btn由谁free?

所以说严格的说是这样:没有重载create或在create过程中没有动态创建对象是可以
更好的说法是:不必要重载destroy时是可以,但如果必须重载destroy来手动释放某些东西的话,
怕是...

 
sonie说的似乎有理,呵呵
如果没有强制类型转换,肯定可以的
但是用了强制类型转换,小弟也糊涂了……
 
可惜只有50分,要不我可做个东西可以完全来测一下。
 
To sonie:
constructor Form1.Create(AOwner:tComponent);override;
begin
inherited Create;
btn:=TButton.Create(this);//self
end;

btn由Form1释放,刚才我已经测试过了。哈哈

测试控件

unit TestButton;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TTestButton = class(TButton)
private
{ Private declarations }
s:TstringList;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:TComponent);override;
Destructor Destroy;override;
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Samples', [TTestButton]);
end;

{ TTestButton }

constructor TTestButton.Create(AOwner: TComponent);
begin
inherited;
s:=TStringList.Create;
end;

destructor TTestButton.Destroy;
begin
s.free;
inherited;

end;

end.

主窗体

unit Main;

interface

uses
SysUtils, Windows, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, Buttons, ExtCtrls, Menus;

type
TMainForm = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
end;

var
MainForm: TMainForm;

implementation

uses Unit1;

{$R *.DFM}

procedure TMainForm.Button1Click(Sender: TObject);
begin
form1:=TForm1.create(self);
end;

procedure TMainForm.Button2Click(Sender: TObject);
var
i:integer;
begin
i:=integer(form1);
TForm(i).free;
end;

end.

{dfm}

object MainForm: TMainForm
Left = 214
Top = 112
Width = 409
Height = 249
Caption = 'MainForm'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = True
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 72
Top = 40
Width = 75
Height = 25
Caption = 'Button1'
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 200
Top = 40
Width = 75
Height = 25
Caption = 'Button2'
TabOrder = 1
OnClick = Button2Click
end
end

测试窗体

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, TestButton;

type
TForm1 = class(TForm)
TestButton1: TTestButton;
private
{ Private declarations }
//s:TStringList;
public
{ Public declarations }
//constructor Create(AOwner:TComponent);override;
//destructor Destroy;override;
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{ TForm1 }

{constructor TForm1.Create(AOwner: TComponent);
begin
inherited;
s:=TStringList.create;
end;

destructor TForm1.Destroy;
begin
s.Free;
inherited;
end;}

end.

{dfm}

object Form1: TForm1
Left = 226
Top = 227
Width = 544
Height = 375
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object TestButton1: TTestButton
Left = 160
Top = 40
Width = 75
Height = 25
Caption = 'TestButton1'
TabOrder = 0
end
end

你可以将测试PAS中的注释部分打开来测试,你会看到是怎样释放对象的。
 
再加200分,大家继续讨论。分数是小事,只要能把问题搞透还可以再加。
 
实际上TForm(i).Free的时候是去查TForm(i)即Form1这实例的Free方法,虽然TForm(i)没显示定义Free
在OOP理论中讲过
 
没有问题 会释放的 你可以自己做个简单的Demo侧一下 我刚刚侧过了
其实如果有问题 VCL的源码里也不会使用那么多的 FreeAndNil过程了 :)给分吧
 
Free, Destroy 是虚函数,属于动态束定,虚函数的调用方法决定了类的成员函数总是
最新的版本。所以当然可以正确执行。你随便找一本 C++ 的书就知道是怎么回事了。
 
多谢各位兄弟,这50分散给参加讨论的大家,不成敬意。djdsz和sonie各100分,等会来取。
 
请djdsz和sonie到“非技术问题”去拿分。
 
haha,你搞错了,mikedeakins的回答是最准确的.
 
sigh... 果然是回答得越长分数越多。
 
mikedeakins不好意思了。
其实说句老实话,我一看到你的答案,我的脸就红了,心想栽了栽了,这回丢人了,灰溜溜地走了。(不过还好,由于水平低下,丢人机会自然也多,所以不过一阵又好了,再则此题我还是有点功劳的,
我不做个反面例子,同志们的形象又咱能这么高大?)
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
625
import
I
I
回复
0
查看
663
import
I
后退
顶部