不要在建構函式和解構函式中呼叫虛擬函式
阿新 • • 發佈:2019-01-31
提到建構函式和解構函式,想必大家肯定是非常瞭解,但是能否在建構函式或是解構函式中呼叫虛擬函式呢?
答案是千萬不要這麼做,這麼做不會得到大家想要的結果。
首先提一下建構函式,建構函式的順序是從基類開始構造->子類,如果在基類中呼叫虛擬函式,由於建構函式基類中僅存在自身
(或其父類,如果存在),不會根據虛擬函式表的規則去呼叫。看如下例子
class Base {
public:
Base() { callVirtual(); }
protected:
virtual callVirtual() { fprintf(stdout, "Base::callVirtual()\n");}
};
class Derived : public Base {
public:
Derived() {}
protected:
virtual callVirtual() { fprintf(stdout, "Derived::callVirtual()\n");}
};
int main() {
Derived d;
}
//結果為Base::callVirtual(),因為在基類構造的過程中還沒有構造派生類,虛擬函式表中派生類的函式並未加入進來
//所以查詢函式的時候只能找到基類的呼叫函式
同理:由於在解構函式中,子類的解構函式已經呼叫過了,在父類的解構函式中也無法訪問子類的虛擬函式表