请教各位大侠一个有关DELPHI中析构函数的问题???(100分)

  • 主题发起人 主题发起人 dolphin2001
  • 开始时间 开始时间
D

dolphin2001

Unregistered / Unconfirmed
GUEST, unregistred user!
我以前是使用C++Build的,由于最近项目的原因开始使用DELPHI。现在碰到一个问题,以前在BCB中定义一个纯虚类,将其析构函数定义为虚函数,然后在此基类的基础上生成两个派生类,这样我若来调用其基类来实现多态的时候,在调用 delete 的方法的时候会自动去调用其派生类的析构函数。
比如:

class CTBase //纯虚类
{
public:
virtual void DoWork(void) = 0

virtual ~CTBase(void)
{
return

}
}


class CTWorkClass
{
private:
CTBase *FBase;
public:
void Work()
{
FBase->DoWork();
}
CTWorkClass(CTBase* InputBase)
{
FBase = InputBase;
}
~CTWorkClass(void)
{
delete FBase
//<---会去自动调用其派生类的析构函数
FBase = NULL;
}
};

class CTFirst : public CTBase //派生类一
{
private:
TStringList* FList

int ListLength

public:
void SetLength(const int value)
{
ListLength = value

}
void DoWork(void)
{
for (int i=ListLength
i>0
i--)
{
FList->Add(IntToStr(i));
}
Application->MessageBox("First Class","SysInfo",0);
} ;
CTFirst(void)
{
FList = new TStringList();
}
~CTFirst(void)
{
delete FList ;
FList = NULL;
}
};

class CTSecond : public CTBase //派生类二
{
public:
void DoWork(void)
{
Application->MessageBox("Second Class","SysInfo",0);
}
CTSecond(void)
{
return;
}
~CTSecond(void)
{
return;
}
};

但我在DELPHI,采用类似的方法,却不能得到在BCB执行的效果:(下面是的代码定义,实现部分已省略)

type
TBase_WorkClass = class
private
FVersion :string;
procedure SetVersion(value:string);
function GetVersion:string;
public
procedure DoWork
virtual;abstract;
procedure DoPrepare
virtual ;abstract;
public
destructor Destroy
virtual ;
published
property Version :string read GetVersion write SetVersion;
end;

type
TFirstClass = class(TBase_WorkClass)
private
FWorkList: TStringList;
FChainCount: Integer;
public
procedure DoWork
override;
procedure DoPrepare
override;
procedure SetChainLength(const ChainLength:Integer);
public
constructor Create;
destructor Destroy
override;
published
property Version;
end;

type
TSecondClass = class(TBase_WorkClass)
public
procedure DoWork
override;
procedure DoPrepare
override;
public
constructor Create;
destructor Destroy
override;
published
property Version;
end;


type
TWorkClass = class
private
FBaseClass:TBase_WorkClass;
public
procedure GotoWork;
public
constructor Create(BaseClass:TBase_WorkClass);
destructor Destroy
override
//跟踪其代码,没有去执行 FBaseClass 的相应派生类的析构函数???
end
 
在你的 Destroy过程中,有没有加inherited;
 
或inherited Destroy;
 
destructor TFirstClass.Destroy;
begin
inherited Destroy;
FWorkList.Free;
end;

constructor TSecondClass.Create;
begin
inherited Destroy;

end;
destructor TBase_WorkClass.Destroy;
begin
inherited;
end;
这是三个类的析构函数的代码,跟踪程序根本没有进到断点的位置???
 
destructor TFirstClass.Destroy;
begin
FWorkList.Free;
inherited Destroy;
end;
把次序调一下.

不太清楚,你是直接调用的,还是工程退出的时候没有进到断点
 
建议多看看 vcl 源代码,
这是VCL中典型多态问题,
 
哦对了,你的基类是 destructor Destroy
virtual ;
虚函数的嘛. 别的析构了吗?
 
楼上,你可以看看我帖出来的代码,有没有什么问题?
 
你贴出来的只是类的定义,没有具体的过程
 
定义没什么问题,不过很多最好不用public,只要外面不直接引用,最好用 protected
 
destructor TBase_WorkClass.Destroy;
begin

end;

function TBase_WorkClass.GetVersion: string;
begin
result := FVersion;
end;

procedure TBase_WorkClass.SetVersion(value:string);
begin
FVersion :=value;
end;

constructor TWorkClass.Create(BaseClass: TBase_WorkClass);
begin
FBaseClass :=BaseClass;
end;

destructor TWorkClass.Destroy;
begin
FBaseClass.free;
// FBaseClass.Destroy;
FBaseClass :=nil;
end;

procedure TWorkClass.GotoWork;
begin
FBaseClass.DoPrepare;
FBaseClass.DoWork;
end;

constructor TFirstClass.Create;
begin
inherited;
FWorkList := TStringList.Create;
end;


destructor TFirstClass.Destroy;
begin
FWorkList.Free;
inherited Destroy

end;

procedure TFirstClass.DoPrepare;
var
i: Integer;
begin
inherited;
for i := FChainCount downto 0 do
begin
FWorkList.Add(IntToStr(i));
end;
end;

procedure TFirstClass.DoWork;
var
TmpString:string;
ShowMsg: array [0..256] of char;
begin
inherited;
TmpString := 'Current Chain Length is '+IntToStr(FChainCount);
StrPCopy(ShowMsg,TmpString);
Application.MessageBox(ShowMsg,'信息',0);
end;

procedure TFirstClass.SetChainLength(const ChainLength: Integer);
begin
FChainCount := ChainLength;
end;

constructor TSecondClass.Create;
begin
inherited Destroy;
end;

destructor TSecondClass.Destroy;
begin

inherited;
end;

procedure TSecondClass.DoPrepare;
begin
inherited;
Application.MessageBox('Second Class ','SysInfo',0);
end;

procedure TSecondClass.DoWork;
begin
inherited;

end;
 
直观感觉问题不大
???下面是不是笔误
constructor TSecondClass.Create;//Create
begin
inherited Destroy;//???Destroy
end;
 
我吃饭去了,晚上有时间再讨论
 
楼上,要不你告诉你的油箱,我发给你,帮忙看看,如何?
 
大侠都来看看!!!
 
搞定了。呵呵
 
怎么搞定的,说说
 
把纯虚类的析构函数去调就行,我查看了一些资料,如果你在DELPHI中自己定义一个类,它默认是从TObject继承下来,而本身TObject的析构函数已经定义为虚函数了,你定义的新类只需要重载就行了,所以只需要在两个派生类中重载destroy方法就行了,
 
constructor TSecondClass.Create;//Create
begin
inherited Destroy;//???Destroy
end;
应该是笔误吧
 

Similar threads

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