Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
Class 我应该在析构函数调用中写入所有它';s字段';Delphi中的析构函数?_Class_Oop_Delphi_Constructor_Pascal - Fatal编程技术网

Class 我应该在析构函数调用中写入所有它';s字段';Delphi中的析构函数?

Class 我应该在析构函数调用中写入所有它';s字段';Delphi中的析构函数?,class,oop,delphi,constructor,pascal,Class,Oop,Delphi,Constructor,Pascal,是否需要调用以释放类的析构函数中的所有字段,或者不需要,但冗长是一种很好的风格?在您给出的示例代码中,确实必须销毁您创建的对象。这是一般规则 如果您的对象继承自TComponent,并且当您调用构造函数传递所有者时,该所有者负责销毁该组件。但是,如果您愿意,也可以在析构函数中释放它 如果创建对象是因为将其分配给接口(由对象实现)类型的变量,则不应销毁(释放)它。这是因为接口是引用计数的,当没有更多的引用时,对象会自动释放。当然,对象必须正确实现引用计数(TInterfacedObject是一个基

是否需要调用以释放类的析构函数中的所有字段,或者不需要,但冗长是一种很好的风格?

在您给出的示例代码中,确实必须销毁您创建的对象。这是一般规则

如果您的对象继承自
TComponent
,并且当您调用
构造函数传递所有者时,该所有者负责销毁该组件。但是,如果您愿意,也可以在
析构函数中释放它


如果创建对象是因为将其分配给
接口
(由对象实现)类型的变量,则不应销毁(释放)它。这是因为接口是引用计数的,当没有更多的引用时,对象会自动释放。当然,对象必须正确实现引用计数(
TInterfacedObject
是一个基类,如果您不想麻烦进行引用计数,可以将其用作祖先。但这是另一回事)。

在您给出的示例代码中,您确实必须销毁您创建的对象。这是一般规则

如果您的对象继承自
TComponent
,并且当您调用
构造函数传递所有者时,该所有者负责销毁该组件。但是,如果您愿意,也可以在
析构函数中释放它


如果创建对象是因为将其分配给
接口
(由对象实现)类型的变量,则不应销毁(释放)它。这是因为接口是引用计数的,当没有更多的引用时,对象会自动释放。当然,对象必须正确实现引用计数(
TInterfacedObject
是一个基类,如果您不想麻烦进行引用计数,可以将其用作祖先。但这是另一个故事)。

是的,但您不是在问“某些语言”——您是在问Delphi。以上对于德尔福来说是正确的。。。对于您询问的情况(基础课),said是正确的。但是,如果您将类基于
TComponent
进行继承,那么您可以编写代码以便指定所有者,然后由所有者负责销毁。这就是表单清理所有子组件的方式。@TomBrunberg当然,其他情况也存在-创建一个实现接口的对象并将其存储在接口变量中,无需显式释放该对象,就像使用类似于
TObjectDictionary
的结构一样,它也实现了所有权层次结构。我想关键是,对象生命周期始终是您需要考虑的问题,只是因为在某些情况下,您不必在代码中显式地执行它,您仍然必须明确地考虑所有对象的生存期,并确保它们将被适当释放,无论是显式地由开发者开发,还是在某些情况下自动实现。它从来都不是全自动的,所以我们在设计新代码时不能忽略它。在析构函数中调用inherited也很重要。如果不这样做,将不会调用祖先析构函数,如果该析构函数实现某些代码,这也可能会导致内存泄漏或其他问题。如果您的祖先是普通类,那么祖先析构函数什么都不做,但调用继承类仍然是一种习惯——这就是冗长和一致有助于避免问题的地方。是的,但您不是在问“某些语言”——您是在问Delphi。以上对于德尔福来说是正确的。。。对于您询问的情况(基础课),said是正确的。但是,如果您将类基于
TComponent
进行继承,那么您可以编写代码以便指定所有者,然后由所有者负责销毁。这就是表单清理所有子组件的方式。@TomBrunberg当然,其他情况也存在-创建一个实现接口的对象并将其存储在接口变量中,无需显式释放该对象,就像使用类似于
TObjectDictionary
的结构一样,它也实现了所有权层次结构。我想关键是,对象生命周期始终是您需要考虑的问题,只是因为在某些情况下,您不必在代码中显式地执行它,您仍然必须明确地考虑所有对象的生存期,并确保它们将被适当释放,无论是显式地由开发者开发,还是在某些情况下自动实现。它从来都不是全自动的,所以我们在设计新代码时不能忽略它。在析构函数中调用inherited也很重要。如果不这样做,将不会调用祖先析构函数,如果该析构函数实现某些代码,这也可能会导致内存泄漏或其他问题。若您的祖先是普通类,那个么祖先析构函数什么也不做,但仍然习惯于调用inherited—这就是冗长和一致有助于避免问题的地方。
TB = Class;
TC = Class;
TA = Class
  Strict Private
      B : TB;
      C : TC;

  Public
      Constructor Create;
      Destructor  Destroy; Override;
      //something
End;

//something 

Constructor TA.Create;
B := TB.Create;
C := TC.Create;
End;

Destructor TA.Destroy;
B.Free;//needed?
C.Free;//needed?
End;