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;
Run Code Online (Sandbox Code Playgroud)
执行:
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;
Run Code Online (Sandbox Code Playgroud)
用法:
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;
Run Code Online (Sandbox Code Playgroud)
为什么我可以将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
Run Code Online (Sandbox Code Playgroud)
现在,您可以init在需要时安全地调用该方法,而不会发生任何意外.
可以在没有"构造"任何东西的情况下调用构造函数的原因是以下代码必须工作:
constructor TTest.Create(const AObject: TObject);
begin //constructor of TTest happens here
inherited Create; //instance call to TParent.Create;
//Other code
end;
Run Code Online (Sandbox Code Playgroud)
在极少数情况下,您可以完全跳过对构造函数的类调用.
以下代码将起作用:
MyTest:= TTest.NewInstance;
//Voodoo code here.
MyTest.Create;
Run Code Online (Sandbox Code Playgroud)
这可以用于防止编译器插入在调用中生成的自动代码TTest.Create.
这很少需要,在20年的编码中我只使用过一次.
这个用例是速度敏感代码,我想避免异常检查的开销和归零分配的空间,这是在Delphi支持带方法的记录之前.
如果我必须再次执行该代码,我将使用一条记录,并在堆上分配一个包含1000条记录的池,并根据需要将其移出.
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |