2 回答

TA貢獻1893條經驗 獲得超10個贊
Java和C++在構造函數中調用虛函數的區別
首先可以認為,Java所有instance函數都是虛函數。
C++類的構造函數中調用虛函數,并不能有多態效果。
這樣設計的理由是:
在基類的構造函數中,派生類的成員尚未初始化,而派生類的虛函數定義可以使用派生類的成員,C++強制必須先初始化對象然后才能使用【這是C++設計new和構造函數的初衷】,所以不可以調用派生類的虛函數定義。
C++虛函數的實現機制也可以解釋這一現象:
對象的虛函數表指針在調用構造函數前更新,指向該類的虛函數表。所以當調用基類的構造函數時,對象的虛函數表指針指向該基類的虛函數表,而不是指向派生類的虛函數表,所以虛函數調用沒有多態效果。
但是
Java類的構造函數中調用虛函數,依然有多態效果。
我是在看《The Java Programming Language, fourth edition》5.5 Inheriting Nested Types 這一節時看到了在Field initializer中調用【虛】函數,仍然有多態的效果,大吃一驚,經驗證屬實。
《Thinking in Java, fourth edition》 Behavior of polymorphic methods inside constructors 這一節對此進行了評論:
If you call a dynamically-bound method inside a constructor, the overridden definition for that method is used. However, the effect of this call can be rather unexpected because the overridden method will be called before the object is fully constructed. This can conceal some difficult-to-find bugs.
總之,這是一把雙刃劍,有利有弊,且弊大于利,要小心使用?!禩he Java Programming Language, fourth edition》5.5 Inheriting Nested Types 這一節舉的例子可以使用兩步初始化的方法解決,也可以使用延遲創建的方法解決,延遲創建是更好的辦法。
C++ 的不懂..幫你找了一下
- 2 回答
- 0 關注
- 1020 瀏覽
添加回答
舉報