Create為什麼可以為虛函式?

2021-04-01 18:47:30 字數 1485 閱讀 8311

今天乙個好友在群裡問:

: 在vcl庫里,大多數建構函式是virtual的,這是為啥

: 按理,在呼叫建構函式之前,物件都還沒有,

: 當然也應該沒有vtbl,那麼這樣virtual有什麼意義呢?

: 所以c++裡的建構函式沒有virtual的。

: 難道delphi裡不是醬紫地?

: 那麼vtbl是在什麼時候被初始化的?

首先,為什麼沒有呼叫建構函式之前,呼叫virtual函式沒有意義,而呼叫實函式就有意義呢?因為虛方法和實方法不同,呼叫實方法的時候,實際上是呼叫類的方法,在例項沒有建立前,就可以呼叫的。而虛方法不同,虛方法依賴於例項,必須要例項的vmt表建立後才能呼叫。

那麼回到主題,為什麼vcl裡很多建構函式是虛函式呢?

因為vcl的初始化實際上都是在newinstance裡完成的。

create只是把最後的堆記憶體,變成可用的指標

在delphi源**裡,可以看到:

class function tobject.newinstance: tobject;

begin

result := initinstance(_getmem(instancesize));

end;

class function tobject.initinstance(instance: pointer): tobject;

varintftable: pinte***cetable;

classptr: tclass;

i: integer;

begin

fillchar(instance^, instancesize, 0);

pinteger(instance)^ := integer(self);

classptr := self;

while classptr <> nil do

begin

intftable := classptr.getinte***cetable;

if intftable <> nil then

for i := 0 to intftable.entrycount-1 do

with intftable.entries[i] do

begin

if vtable <> nil then

pinteger(@pchar(instance)[ioffset])^ := integer(vtable);

end;

classptr := classptr.classparent;

end;

result := instance;

end;

可以看出,最終的構造是在newinstance裡完成。

後記:本來問題到這裡就結束了,誰知道哪天看書,發現原來newinstance也是虛函式。$%#^$%^$#@!!那是怎麼回事呢?原來是自己想多了,***.create呼叫的是類的方法,而在delphi裡,類在程序啟動的時候已經初始化了,虛擬表也存在,所以。。。。。。

建構函式為什麼不可以為虛函式

1,從儲存空間角度 虛函式對應乙個vtable,這大家都知道,可是這個vtable其實是儲存在物件的記憶體空間的。問題出來了,如果建構函式是虛的,就需要通過 vtable來呼叫,可是物件還沒有例項化,也就是記憶體空間還沒有,無法找到vtable,所以建構函式不能是虛函式。2,從使用角度 虛函式主要用...

建構函式可以為虛函式嗎?

答案當然是否定的,主要從一下兩個角度加以說明。從儲存空間角度 虛函式對應乙個vtable,可是這個vtable其實是儲存在物件的記憶體空間的。那麼問題來了,如果建構函式是虛函式,就要通過vtable來呼叫,可是物件空間還沒有例項化,也就是記憶體空間還沒有,無法找到vtable,所以建構函式不能是虛函...

析構函式為何可以為虛函式?

首先要明確 1.每個析構函式 不加 virtual 只負責清除自己的成員。2.可能有基類指標,指向的確是派生類成員的情況。這是很正常的 那麼當析構乙個指向派生類成員的基類指標時,程式就不知道怎麼辦了。所以要保證執行適當的析構函式,基類中的析構函式必須為虛析構。基類指標可以指向派生類的物件 多型性 如...