虛函式問題

2021-07-04 03:56:28 字數 2399 閱讀 6074

inline, static, constructor三種函式都不能帶有virtual關鍵字。

inline是編譯時展開,必須有實體;

static屬於class自己的,也必須有實體;

virtual函式基於vtable(記憶體空間),constructor函式如果是virtual的,呼叫時也需要根據vtable尋找,但是constructor是virtual的情況下是找不到的,因為constructor自己本身都不存在了,建立不到class的例項,沒有例項,class的成員(除了public static/protected static for friend class/functions,其餘無論是否virtual)都不能被訪問了。

常見的不不能宣告為虛函式的有:普通函式(非成員函式);靜態成員函式;內聯成員函式;建構函式;友元函式。

1.為什麼c++不支援普通函式為虛函式?

普通函式(非成員函式)只能被overload,不能被override,宣告為虛函式也沒有什麼意思,因此編譯器會在編譯時邦定函式。

2.為什麼c++不支援建構函式為虛函式?

這個原因很簡單,主要是從語義上考慮,所以不支援。因為建構函式本來就是為了明確初始化物件成員才產生的,然而virtual function主要是為了再不完全了解細節的情況下也能正確處理物件。另外,virtual函式是在不同型別的物件產生不同的動作,現在物件還沒有產生,如何使用virtual函式來完成你想完成的動作。(這不就是典型的悖論)

3.為什麼c++不支援內聯成員函式為虛函式?

其實很簡單,那內聯函式就是為了在**中直接展開,減少函式呼叫花費的代價,虛函式是為了在繼承後物件能夠準確的執行自己的動作,這是不可能統一的。(再說了,inline函式在編譯時被展開,虛函式在執行時才能動態的邦定函式)

4.為什麼c++不支援靜態成員函式為虛函式?

這也很簡單,靜態成員函式對於每個類來說只有乙份**,所有的物件都共享這乙份**,他也沒有要動態邦定的必要性。

5.為什麼c++不支援友元函式為虛函式?

因為c++不支援友元函式的繼承,對於沒有繼承特性的函式沒有虛函式的說法

。為什麼內聯函式,建構函式,靜態成員函式不能為virtual函式?

1> 內聯函式

內聯函式是在編譯時期展開,而虛函式的特性是執行時才動態聯編,所以兩者矛盾,不能定義內聯函式為虛函式。

2> 建構函式

建構函式用來建立乙個新的物件,而虛函式的執行是建立在物件的基礎上,在建構函式執行時,物件尚未形成,所以不能將建構函式定義為虛函式。

3> 靜態成員函式

靜態成員函式屬於乙個類而非某一物件,沒有this指標,它無法進行物件的判別。

這個可以從兩個角度去理解:

1。virtual意味著在執行時期進行繫結,所以在編譯時刻需確定資訊的不能為virtual

建構函式需在編譯時刻,因為需構造出個物件,才能執行動作。

靜態成員函式不屬於任何乙個物件,編譯時刻確定不存在執行的時候選擇執行哪個的情形。

內聯函式,由於屬於編譯器的建議機制,所以其實可以virtual。

2。virtual意味著派生類可以改寫其動作

派生類的建構函式會先執行基類的建構函式而不是取代基類建構函式,也就是說基類的建構函式可以看作派生類建構函式的組成,所以並不能改寫這個函式。

靜態成員函式不屬於任何乙個物件,所以更不能改寫其動作了。

inline和virtual不會同時起作用。

帶virtual的函式在不需要動態繫結呼叫的時候,就可以inline。

虛建構函式(virtual constructor)

c++ 不支援直接的虛建構函式。虛擬機制的設計目的是使程式設計師在不完全了解細節(比如只知該類實現了某個介面,而不知該類確切是什麼東東)的情況下也能使用物件。但是,要建立乙個物件,可不能只知道「這大體上是什麼」就完事——你必須完全了解全部細節,清楚地知道你要建立的物件是究竟什麼。所以,建構函式當然不能是虛的了。但是,可通過虛函式 virtual clone()(對於拷貝建構函式)或虛函式 virtual create()(對於預設建構函式),得到虛建構函式產生的效果。注意:子類成員函式clone()的返回值型別故意與父類成員函式clone()的不同。這種特徵被稱為「協變的返回型別」(covariant return types),該特徵最初並不是c++語言的一部分,vc6.0以下版本編譯器不支援這樣的寫法。

虛析構函式(virtual destructor)

當你可能通過基類指標刪除派生類物件時,建議使用虛析構函式。虛函式繫結到物件的類的**,而不是指標/引用的類。如果基類有虛析構函式,delete baseptr(基類指標)時,*baseptr 的物件型別的析構函式被呼叫,而不是該指標的型別的析構函式。簡單講,這個類有虛函式就應該有虛析構函式。一旦你在類中加上了乙個虛函式,你就已經需要為每乙個物件支付空間代價(每個物件乙個指標),所以這時使析構函式成為虛擬的通常不會額外付出什麼。

對於那些trivial且沒有子類的類,虛析構函式只會增加開銷,不要使用。

C 虛函式問題

1定義乙個函式式虛函式是為了允許 用基類的指標來呼叫子類的的這個函式。比如下面 這個類的函式呼叫不是在編譯的時候被確定,而是執行的時候被確定。include using namespace std class a 2根據網上部落格,簡單理解虛函式以及虛函式表。虛函式是根據虛函式表來實現的,這個表分配...

C 虛函式問題

1.建構函式中可以呼叫虛函式嗎 可以,只是不會產生動態行為,因為建構函式是從基類開始構造,基類在呼叫虛函式時,子類還未構造,所以呼叫的是基類的函式。2.析構函式可以呼叫虛函式嗎 如果在父類析構函式中呼叫虛函式,其實際呼叫的是子類的函式,而此時子類析構函式已經把資料銷毀了,會出現不可知的結果。3.析構...

虛函式相關問題

1 什麼是虛函式?虛函式是在類中由virtual關鍵字宣告的成員函式,並且每乙個含有虛函式的類都會至少有乙個與之對應的虛函式表,用來存放該類所有虛函式對應的函式指標。所有虛函式位址都會存放在所屬類的虛函式表中,子類會繼承父類的虛函式表,若是子類中有與父類相同的虛函式,則會構成重寫,此時子類的虛函式指...