数据成员释放的问题 ( 积分: 50 )

  • 主题发起人 主题发起人 awfigsk
  • 开始时间 开始时间
A

awfigsk

Unregistered / Unconfirmed
GUEST, unregistred user!
还是刘艺老师所写的编程思想这本书的第95页
unit Demo;
...
type
...
TWheel=class(TObject)
private
...
public
constructor create;
procedure start;
procedure stop;
end;

TVehicle=class(TObject)
protected
...
FWheels:TList;
end;

TBicycle=class(TVehicle)
public
constructor create;
destructor Destory;
...
end;

implementation

constructor TBicycle.create;
var
i:integer;
begin
...
FWheels:=TList.create;
for i:=1 to 2 do
FWheels.Add(TWheel.create(21,'B型自行车车轮',i));
end;

destructor TBicycle.destory;
var
i:Integer;
begin
for i:=1 to 2 do
TWheel(FWheels.Items).Free;
inherited;
end;

....

我想请问一下,为何在TBicycle.destory方法中,要加入
TWheel(FWheels.Items).Free

FWheels不是TBicycle父类TVehicle的数据成员吗,在TBicycle释放时,难道不会自动释放FWheels这个数据成员吗?
[red]是不是因为TVehicle类没有重写析构函数?[/red]

还请大侠们指点,谢谢!
 
还是刘艺老师所写的编程思想这本书的第95页
unit Demo;
...
type
...
TWheel=class(TObject)
private
...
public
constructor create;
procedure start;
procedure stop;
end;

TVehicle=class(TObject)
protected
...
FWheels:TList;
end;

TBicycle=class(TVehicle)
public
constructor create;
destructor Destory;
...
end;

implementation

constructor TBicycle.create;
var
i:integer;
begin
...
FWheels:=TList.create;
for i:=1 to 2 do
FWheels.Add(TWheel.create(21,'B型自行车车轮',i));
end;

destructor TBicycle.destory;
var
i:Integer;
begin
for i:=1 to 2 do
TWheel(FWheels.Items).Free;
inherited;
end;

....

我想请问一下,为何在TBicycle.destory方法中,要加入
TWheel(FWheels.Items).Free

FWheels不是TBicycle父类TVehicle的数据成员吗,在TBicycle释放时,难道不会自动释放FWheels这个数据成员吗?
[red]是不是因为TVehicle类没有重写析构函数?[/red]

还请大侠们指点,谢谢!
 
你的TWheel实例是在TBicycle创建时创建的,必须要释放

创建和释放要一一对应
 
FWheels不是TVehicle类的成员么

为什么在TBicycle类的create中有这个代码?
FWheels:=TList.create;

那么好的,就算这个代码在TBicycle类中存在是合理的,那么谁创建不应该谁释放的么?
为什么我在TBicycle类的destroy里面没看到
FWheels.free;
这个代码?
 
FWheels 和TWheel(FWheels.Items)不是一个东西
FWheels是一个TList
TWheel从头到尾没有命名的,只是创建后把指针放在了FWheels中
 
是呀,为何在TBicycle的Destory函数中没有FWheels.Free呢?
程序在定义中可能多写了TVehicle的构造函数create,在实现部分有这一块内容,我敲上来。(但没有TVechicle析构函数实现)

constructor TVehicle.create;
begin
...
FWheel:=nil;
FWheels:=nil;
end;

下面是光盘所带的原代码:
unit Demo;

interface

uses
SysUtils, Windows, Messages,Classes,Dialogs;

type
TEngine = class (TObject)
private
FCapacity: Integer;
FPower: Integer;
public
constructor create;
procedure start;
procedure stop;
end;

TWheel = class (TObject)
private
FNo: Integer;
FSize: Integer;
FTypeName: string;
procedure check;
public
constructor create(size:Integer;TypeName:string;No:Integer);
end;

TVehicle = class (TObject)
protected
FColor: string;
FMake: string;
FTopSpeed: Integer;
FWheel: TWheel;
FWheels: TList;
procedure SlowDown;
procedure SpeedUp;
procedure Start;
procedure Stop;
end;

TBicycle = class (TVehicle)
public
constructor create;
destructor Destory;
procedure ride;
end;

TCar = class (TVehicle)
protected
FEngine: TEngine;
public
constructor create;
destructor Destory;
procedure drive;
end;

implementation

{
*********************************** TBicycle ***********************************
}
constructor TBicycle.create;
var
i: Integer;
begin
FColor:='白色';
FMake:='永久';
FTopSpeed:=20;
ShowMessage(FColor+FMake+'车,最高时速:'+IntToStr(FTopSpeed));
FWheels:= TList.Create;
for i:=1 to 2 do
FWheels.Add(TWheel.create(21,'B型自行车车轮',i));
end;

destructor TBicycle.Destory;
var
i: Integer;
begin
for i:=1 to 2 do
TWheel(FWheels.Items).Free;
inherited;
end;

procedure TBicycle.ride;
begin
start;
speedUp;
showmessage('自行车车行驶中...');
SlowDown;
Stop;
end;

{
************************************* TCar *************************************
}
constructor TCar.create;
var
i: Integer;
begin
FEngine:=TEngine.create;
FColor:='黑色';
FMake:='红旗';
FTopSpeed:=200;
ShowMessage(FColor+FMake+'车,最高时速:'+IntToStr(FTopSpeed));
FWheels:= TList.Create;
for i:=1 to 4 do
FWheels.Add(TWheel.create(36,'A型汽车车轮',i));
end;

destructor TCar.Destory;
var
i: Integer;
begin
for i:=1 to 4 do
TWheel(FWheels.Items).Free;
FEngine.Free;
inherited;
end;

procedure TCar.drive;
begin
start;
FEngine.start;
speedUp;
showmessage('汽车行驶中...');
SlowDown;
FEngine.stop;
Stop;
end;

{
*********************************** TEngine ************************************
}
constructor TEngine.create;
begin
Fcapacity:=1500;
Fpower:=130;
end;

procedure TEngine.start;
begin
ShowMessage(inttostr(Fcapacity)+'cc,'+inttostr(Fpower)+'匹马力的发动机发动了!');
end;

procedure TEngine.stop;
begin
ShowMessage('发动机关闭了');
end;

{
*********************************** TVehicle ***********************************
}

procedure TVehicle.SlowDown;
begin
ShowMessage('正在减速...');
end;

procedure TVehicle.SpeedUp;
begin
ShowMessage('正在加速...');
end;

procedure TVehicle.Start;
begin
ShowMessage('车子开始启动');
end;

procedure TVehicle.Stop;
begin
ShowMessage('车子停下');
end;

{
************************************ TWheel ************************************
}
constructor TWheel.create(size:Integer;TypeName:string;No:Integer);
begin
FSize:=size;
FTypeName:=TypeName;
FNo:=No;
check;
end;

procedure TWheel.check;
begin
ShowMessage('检查第'+IntToStr(FNo)+'个车轮。型号:'+FTypeName+' 大小:'+IntToStr(FSize));
end;


end.
 
是不是由于FWheels是类TBicycle的一个数据成员,在TBicycle的实例对象消毁时,会自动清除FWheels这个数据成员?
 
即使FWheels是类TBicycle的一个数据成员,如果创建了,在TBicycle的实例对象消毁时不会释放的,这样会造成内存泄漏
 
1、向Tlist类中添加对象时只是添加了对象的指针。
所以在释放时,需要自己释放所创建的对象。
2、FWheels作为类TBicycle的一个数据成员,其也仅是一个指针。
对象实例也需要自己释放。
否则会造成内存泄漏。

 
是不是如果数据成员是指针话,则要对象实例进行释放?
其他类型,如整数,字符串就不需要对象实例进行释放?
是这样吗?还请指点,谢谢!

type
TTest1=class
private
fField1:integer;
fField2:TList;
end;

constructor TTest1.create;
begin
fField1:=1;
fField2:=Tlist.create;
end;

destructor TTest1.Destory
begin
[red]fField2.Free
//这里要对fField2进行释放?
fField2:=nil
//这一步需要吗?[/red]
end;
 
可以这样说的
 
>>是不是如果数据成员是指针话,则要对象实例进行释放?
我觉得谁创建的谁就负责释放,跟它是不是指针没直接关系
 
谢谢各位大侠指点,分数奉上!
 
后退
顶部