Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi类def导致EStackOverflow_Delphi_Class_Destructor - Fatal编程技术网

Delphi类def导致EStackOverflow

Delphi类def导致EStackOverflow,delphi,class,destructor,Delphi,Class,Destructor,我有一个使用class的应用程序,一个叫做TBaseDB的基类,将会有很多TBaseDB的后代,都是直接的兄弟,现在只有一个已经启动了,TOraDB,但稍后会添加TSQLDB和其他 我的应用程序使用该类的一个实例,它是一个全局实例,即一个名为PROJ的全局变量。在我对构造函数、析构函数和全局变量的理解中,有一个问题导致了应用程序中其他地方的EStackOverflow。如果我注释掉我的PROJ.CREATE,EStackOverflow就会消失 我的构造函数只设置变量,不动态创建链表、aray或

我有一个使用class的应用程序,一个叫做TBaseDB的基类,将会有很多TBaseDB的后代,都是直接的兄弟,现在只有一个已经启动了,TOraDB,但稍后会添加TSQLDB和其他

我的应用程序使用该类的一个实例,它是一个全局实例,即一个名为PROJ的全局变量。在我对构造函数、析构函数和全局变量的理解中,有一个问题导致了应用程序中其他地方的EStackOverflow。如果我注释掉我的PROJ.CREATE,EStackOverflow就会消失

我的构造函数只设置变量,不动态创建链表、aray或其他内存密集型对象

下面是一些代码片段

// global var definition
// Specifically of BASE class, so I can call any child class without knowing which child class it is...
PROJ : TBaseDB;
我的例行程序导致了我的错误

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;
这是我的类定义

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;
这是我对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;
我不理解“重置”全局类变量的某些内容。我应该在哪里“重置它,这样我仍然可以使用全局变量PROJ”

谢谢

你不能在类的析构函数中调用Self.Free

免费电话销毁和销毁免费电话。。。。。。直到堆栈溢出

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;
Free只是析构函数的一个安全调用,因为它将测试实例是否为nil

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;
您应该看看单例实现。

您不能在类的析构函数中调用Self.Free

免费电话销毁和销毁免费电话。。。。。。直到堆栈溢出

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;
Free只是析构函数的一个安全调用,因为它将测试实例是否为nil

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;
您应该看看单例实现。

不要使用:

  Self.Free;
  Self := nil;
在析构函数中。不要使用:

  Self.Free;
  Self := nil;

在你的析构函数中。

被鲁福爵士打败:——@鲁福爵士,你说过不应该,但在你的回答中不能更好地使用。。。不应该给你这样做的自由。@TLama你是对的,应该用红色大字写:哦,我编辑了我的回答,被鲁福爵士打败了:-鲁福爵士,你说过不应该,但在你的回答中不能更好地使用。。。不应该给你这样做的自由。@TLama你是对的,应该用红色大字写:o我编辑了我的回答。那么,如果我没有创建任何“特殊”内存对象,而只是创建基字符串等,调用继承的就足够了吗?i、 例如,是否在析构函数中继承了-all-i need?@user1009073是的,但只在析构函数中继承了,根本不需要派生析构函数。简单的规则是,构造函数中的每个FObj:=TSomeObject.Create都要与析构函数中的一个FObj.Free配对。然后按与创建顺序相反的顺序释放它们。那么,如果我不创建任何“特殊”内存对象,而只是创建基字符串等,那么调用继承对象就足够了吗?i、 例如,是否在析构函数中继承了-all-i need?@user1009073是的,但只在析构函数中继承了,根本不需要派生析构函数。简单的规则是,构造函数中的每个FObj:=TSomeObject.Create都要与析构函数中的一个FObj.Free配对。按与创造顺序相反的顺序释放它们。