Tor*_*edo 2 delphi constructor
我很困惑:为什么显式调用Delphi构造函数/作为普通方法不会创建新实例/为什么没有内存泄漏?
这是一些示例代码:
TMyHelperClass = class(TObject)
private
  fSomeHelperInt: integer;
public
  property SomeHelperInt : integer read fSomeHelperInt write fSomeHelperInt;
  constructor Create (const initSomeHelperInt : integer);
end;
TMyClass = class(TObject)
private
  fHelper : TMyHelperClass;
public
  constructor Create(const initSomeInt: integer);
  destructor Destroy; override;
  property Helper : TMyHelperClass read fHelper;
end;
执行:
constructor TMyHelperClass.Create(const initSomeHelperInt: integer);
begin
  fSomeHelperInt := initSomeHelperInt;
end;
constructor TMyClass.Create(const initSomeInt: integer);
begin
  fHelper := TMyHelperClass.Create(initSomeInt);
end;
destructor TMyClass.Destroy;
begin
  fHelper.Free;
  inherited;
end;
用法:
var
  my : TMyClass;
begin
  my := TMyClass.Create(2016);
  try
    //WHY is this ok to be used ?
    my.Helper.Create(2017);
  finally
    my.Free;
  end;
end;
为什么我可以将TMyHelperClass +的Create构造函数称为普通方法?我的意思是 - 这正是我想要的 - 但是怎么没有问题(有记忆)?
我想答案是因为Create方法没有像TMyHelperClass.Create那样被调用(用于创建TMyHelperClass的实例)?
这种调用构造函数的方式是否可以使用普通方法/ ok?
Joh*_*ica 10
是的,您可以将构造函数作为普通方法调用.
这样做是不好的做法.  
为什么没有内存泄漏?
来自:http://docwiki.embarcadero.com/RADStudio/Seattle/en/Methods#Constructors
使用对象引用(而不是类引用)调用构造函数时,它不会创建对象.相反,构造函数对指定的对象进行操作,仅执行构造函数实现中的语句,然后返回对该对象的引用.通常在对象引用上调用构造函数,并结合继承的保留字来执行继承的构造函数.
调用TObject.Create (类引用) vs AObject.Create (实例引用)时,编译器将生成不同的代码.
反模式警告
 
滥用构造函数作为常规方法将导致分配资源时出现问题.
通常构造函数和析构函数是匹配的,但是如果你调用构造函数两次(就像调用实例的构造函数时一样),你将分配资源两次,但只释放一次.
如果要将构造函数的主体作为普通方法调用,请创建一个新方法并在构造函数中调用该方法.
例如:
constructor TTest.Create;
begin
  inherited;
  //Allocate needed resources here.
  Init;
end;
procedure TTest.Init;
begin
  //Do initialization stuff
  //But don't allocate any resources
现在,您可以init在需要时安全地调用该方法,而不会发生任何意外.  
可以在没有"构造"任何东西的情况下调用构造函数的原因是以下代码必须工作:
constructor TTest.Create(const AObject: TObject);
begin                //constructor of TTest happens here
  inherited Create;  //instance call to TParent.Create;
  //Other code
end;
在极少数情况下,您可以完全跳过对构造函数的类调用.
以下代码将起作用:
MyTest:= TTest.NewInstance;
//Voodoo code here.
MyTest.Create;
这可以用于防止编译器插入在调用中生成的自动代码TTest.Create.
这很少需要,在20年的编码中我只使用过一次.
这个用例是速度敏感代码,我想避免异常检查的开销和归零分配的空间,这是在Delphi支持带方法的记录之前.  
如果我必须再次执行该代码,我将使用一条记录,并在堆上分配一个包含1000条记录的池,并根据需要将其移出.
| 归档时间: | 
 | 
| 查看次数: | 286 次 | 
| 最近记录: |