C++進階--建構函式和解構函式中的虛擬函式
阿新 • • 發佈:2018-12-23
//############################################################################ /* 任何時候都不要在建構函式或解構函式中呼叫虛擬函式 */ class dog { public: string m_name; dog(string name) {m_name = name; bark();} virtual void bark() { cout<< "Woof, I am just a dog " << m_name << endl;} }; class yellowdog : public dog { public: yellowdog(string name) : dog(string name) {...} virtual void bark() { cout << "Woof, I am a yellow dog " << m_name << endl; } }; int main () { yellowdog mydog("Bob"); } 輸出: Woof, I am just a dog Bob. /* 在構造的過程中,所有虛擬函式表現為非虛擬函式 為什麼? 基類在派生類之前構造。 所以bark()的時候,yellowdog還沒有構造 為什麼Java中表現不一樣? Java和C++在定義物件的生命週期上有一個基本的差異 Java: 所有成員在建構函式執行前被null初始化。生命週期在建構函式之前已經開始 C++: 建構函式負責初始化成員。生命週期在建構函式結束之後才開始 呼叫物件中還未被初始化的部分是繼承危險的 呼叫物件中已經被delete的部分也是危險的 */ /* 解決方法 1: 不使用多型,使用初始化引數來產生執行時差異 */ class dog { public: ... dog(string name, string color) {m_name = name; bark(color);} void bark(string str) { cout<< "Woof, I am "<< str << " dog " << m_name << endl;} }; class yellowdog : public dog { public: yellowdog(string name):dog(name, "yellow") {} }; int main () { yellowdog mydog("Bob"); } 輸出: Woof, I am yellow dog Bob /* 解決方法 2: 使用私有靜態成員函式,不同派生類可執行不同操作 */ class dog { public: ... dog(string name, string woof) {m_name = name; bark(woof);} dog(string name) {m_name = name; bark( getMyColor() );} void bark(string str) { cout<< "Woof, I am "<< str << " dog " << m_name << endl;} private: static string getMyColor() {return "just a";} }; class yellowdog : public dog { public: yellowdog(string name):dog(name, getMyColor()) {} private: static string getMyColor() {return "yellow";} //Why static? }; int main () { yellowdog mydog("Bob"); } OUTPUT: Woof, I am yellow dog Bob