gpt4 book ai didi

delphi - Delphi:重载不会调用重写的虚拟构造函数后代

转载 作者:行者123 更新时间:2023-12-03 19:01:06 25 4
gpt4 key购买 nike

关于德尔福构造函数的一系列问题中的另一个问题。

我有一个具有虚拟构造函数的基类:

TComputer = class(TObject)
public
constructor Create(Teapot: Integer); virtual;
end;


在有人需要调用的时候,构造函数是虚拟的

var
computerClass: class of TComputer;
computer: TComputer;
begin
computer := computerClass.Create(nTeapot);


子代的构造函数为 overridden

TCellPhone = class(TComputer) 
public
constructor Create(Teapot: Integer); override;
end;

TiPhone = class(TCellPhone )
public
constructor Create(Teapot: Integer); override;
end;


其中 TCellPhoneTiPhone子孙各自都有机会进行自己的初始化(出于可读性考虑,不包括这些成员)。

但是现在我向某些祖先添加了一个重载的构造函数:

TCellPhone = class(TComputer) 
public
constructor Create(Teapot: Integer); override; overload;
constructor Create(Teapot: Integer; Handle: string); overload;
end;


TCellPhone中的备用构造函数将调用另一个虚拟构造函数,因此它始终会获得正确的覆盖行为:

constructor TCellPhone.Create(Teapot: Integer; Handle: string);
begin
TCellPhone.Create(Teapot); //call sibling virtual constructor

FHandle := Handle;
end;


问题在于,永远不会调用后代,重写的构造函数。实际的堆栈跟踪调用链为:

phone := TiPhone.Create(37, 'spout')
constructor TCellPhone.Create(Teapot: Integer; Handle: string)
constructor TCellPhone.Create(Teapot: Integer)
constructor TComputer.Create(Teapot: Integer)
TObject.Create


TCellPhone.Create(int)的同级调用是虚拟的,应该在 TiPhone中调用后代,重写的方法:

phone := TiPhone.Create(37, 'spout')
constructor TCellPhone.Create(Teapot: Integer; Handle: string)
constructor TiPhone.Create(Teapot: Integer)
constructor TCellPhone.Create(Teapot: Integer)
constructor TComputer.Create(Teapot: Integer)
TObject.Create


因此,似乎使用Delphi的同级虚拟构造函数的尝试无法按预期进行。

那么,一个构造函数使用另一个构造函数是一个坏主意吗?设计意图是使重载构造函数中的代码相互复制粘贴吗?

我在.NET中注意到,一些构造函数相互链接:

public Bitmap(int width, int height) : this(width, height, PixelFormat.Format32bppArgb) {}

public Bitmap(int width, int height, PixelFormat format) {...}


仅在以下情况下这才是问题:


构造函数是虚拟的
你重载了构造函数


您不能让一个构造函数重载另一个规则的规则吗?

最佳答案

错误..

应该是:

constructor TCellPhone.Create(Teapot: Integer; Handle: string);
begin
TCellPhone.Create(Teapot); //call sibling virtual constructor

FHandle := Handle;
end;

您只是在创建一个新的Cellphone实例,而没有调用其他Create方法。

关于delphi - Delphi:重载不会调用重写的虚拟构造函数后代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3892258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com