use*_*073 1 delphi destructor class
我有一个使用类的应用程序,一个名为TBaseDB的基类,并且会有许多TBaseDB的后代,所有DIRECT兄弟,现在只有一个已经启动,TOraDB,但稍后会添加TSQLDB等.
我的应用程序使用该类的一个实例,它是一个全局实例,即一个名为PROJ的全局变量.我对构造函数,析构函数和全局变量的理解存在一个问题,它导致EStackOverflow在应用程序的其他位置.如果我注释掉我的PROJ.CREATE,EStackOverflow就会消失.
我的构造函数只能设置变量,它们不会动态创建链表,数组或其他内存密集型对象.
以下是一些代码段.
// global var definition
// Specifically of BASE class, so I can call any child class without knowing which child class it is...
PROJ : TBaseDB;
Run Code Online (Sandbox Code Playgroud)
我的例程导致我的错误......
procedure TForm1.ShowBug;
begin
// We have clicked on 'Create New Oracle Project
// Now create our PROJ object.
// This is defined globally, but MAY have been used before
// so 'zero' it out
FreeAndNil(PROJ);
// Note that the create is on the CHILD class, not the BASE class
// If I DON'T create the class, no error....
PROJ := TOraDB.Create;
// ... other code
end;
Run Code Online (Sandbox Code Playgroud)
这是我的课程定义.
Type
TBaseDB = class
published
public
DAC_ID: Integer;
DAC_ShortName : String;
DAC_LongName: String;
Constructor Create;
Destructor Destroy; override;
... other stuff
end;
implementation
// TBaseDB /////////////////////////////////////////////////////////////////
constructor TBaseDB.Create;
begin
inherited;
end;
destructor TBaseDB.Destroy;
begin
// If I comment out next two lines, my issue goes away
// but shouldn't I have them....?
Self.Free;
Self := nil;
// Always call the parent destructor after running your own code
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
这是我对TOraDB类的定义
Type
TOraDB = Class(TBaseDB)
public
Constructor Create;
Destructor Destroy; override;
... other stuff
End;
implementation
// ------------------------------------------------------------------------------
constructor TOraDB.Create;
begin
inherited;
// Now set up the information about the source database. We know it is Oracle
// even though we DONT know if it is connected
DAC_ID := 4;
DAC_ShortName := 'Ora';
DAC_LongName := 'Oracle';
end;
// -----------------------------------------------------------------------------
destructor TOraDB.Destroy;
begin
// Always call the parent destructor after running your own code
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
我不了解'重置'全局类变量.我应该在哪里'重置它,所以我仍然可以使用GLOBAL变量PROJ?
谢谢,
GS
Sir*_*ufo 12
你不能Self.Free在类的析构函数中调用.
免费调用Destroy and Destroy calls Free ......直到Stack Overflow
destructor TBaseDB.Destroy;
begin
// Don't do that at all in a destructor
// Self.Free;
// Self := nil;
// Always call the parent destructor after running your own code
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
TObject.Free 只是对析构函数的安全调用,因为它将测试Instance是否为零.
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
Run Code Online (Sandbox Code Playgroud)
编辑
关于全局变量,PROJ有一个简单(但不是非常明智)的解决方案
destructor TBaseDB.Destroy;
begin
if Self = PROJ then
PROJ := nil;
// Always call the parent destructor after running your own code
inherited;
end;
Run Code Online (Sandbox Code Playgroud)
您应该看一下Singleton实现.