邁克爾,
我明白你的問題,但因爲你的源代碼不能編譯,我想你好想你的問題;-)
我的回答是有點什麼梅森的闡述的點試圖在他的第二個答案中解釋。
問題就在於你的問題實現了你有一個'類引用'(如TClass或TComponentClass),它引用了一個具有虛擬構造函數的基類。 但是,TClass不會(TClass引用具有非虛擬構造函數的類),但是TComponentClass會這樣。
通過使用類引用分解對構造函數的調用時,您會看到不同之處。 當你調用通過類虛擬參考構造函數,代碼是當你調用一個非虛構造比略有不同:
這拆卸表明我的意思:
TestingForVirtualConstructor.dpr.37: ComponentClassReference := TMyComponentClass;
00416EEC A1706D4100 mov eax,[$00416d70]
TestingForVirtualConstructor.dpr.38: Instance := ComponentClassReference.Create(nil); // virtual constructor
00416EF1 33C9 xor ecx,ecx
00416EF3 B201 mov dl,$01
00416EF5 FF502C call dword ptr [eax+$2c]
TestingForVirtualConstructor.dpr.39: Instance.Free;
00416EF8 E8CFCDFEFF call TObject.Free
TestingForVirtualConstructor.dpr.41: ClassReference := TMyClass;
00416EFD A1946E4100 mov eax,[$00416e94]
TestingForVirtualConstructor.dpr.42: Instance := ClassReference.Create(); // non-virtual constructor
00416F02 B201 mov dl,$01
00416F04 E893CDFEFF call TObject.Create
TestingForVirtualConstructor.dpr.43: Instance.Free;
00416F09 E8BECDFEFF call TObject.Free
所以,當你有一個變量o f類構造函數是虛擬的類引用,並且通過該變量調用該構造函數,您可以確定該變量中的實際類將具有虛擬構造函數。
您無法確定構造函數實現的實際類(沒有額外的調試信息,例如.DCU,.MAP,.JDBG或其他來源)。
下面是示例代碼,做編譯:
program TestingForVirtualConstructor;
{$APPTYPE CONSOLE}
uses
Classes, SysUtils;
type
TMyComponentClass = class(TComponent)
MyStrings: TStrings;
constructor Create(Owner: TComponent); override;
end;
constructor TMyComponentClass.Create(Owner: TComponent);
begin
inherited;
end;
type
TMyClass = class(TObject)
MyStrings: TStrings;
constructor Create();
end;
constructor TMyClass.Create();
begin
inherited;
end;
procedure Test;
var
// TComponentClass has a virtual constructor
ComponentClassReference: TComponentClass;
ClassReference: TClass;
Instance: TObject;
begin
ComponentClassReference := TMyComponentClass;
Instance := ComponentClassReference.Create(nil); // virtual constructor
Instance.Free;
ClassReference := TMyClass;
Instance := ClassReference.Create(); // non-virtual constructor
Instance.Free;
end;
begin
try
Test;
except
on E: Exception do
Writeln(E.Classname, ': ', E.Message);
end;
end.
要回到你原來的問題: 當你的類引用引用具有虛擬構造一個基類,你確信你將永遠打電話一個使用間接的虛擬構造函數。 當你的類引用引用了一個具有非虛擬構造函數的基類時,你可以確定你將總是使用直接調用來調用非虛構造函數。
希望這可以讓你更清楚地瞭解你的問題。
--jeroen
...如果你需要這個信息的話,我認爲你正在做的事情錯了... – Alex 2009-04-26 16:15:37
是的,沒錯,我要檢查,如果事情是錯在偷別人的代碼。如果構造函數沒有被聲明爲虛擬的,它將不會被調用,所以「真正的壞事可能發生」。 – mjn 2009-04-26 16:38:23