C++繼承中的對象構造與析構和賦值重載詳解
一、構造/析構順序及繼承性
class A { private: int _a; public: A(int a = 0): _a(a) { cout << "A()" << this << endl; } ~A() { cout << "~A()"<< this <<endl; } }; class B : public A { private: int _b; public: B(int b): _b(b), A() { cout << "B()" << this << endl; } ~B() { cout << "~B()"<< this <<endl; } };
結論:
1.構造順序:先構造基類,後構造派生類
2.析構順序:先析構派生類,後析構基類
二、拷貝構造的繼承性
class A { private: int _a; public: A(int a = 0): _a(a) { cout << "A()" << this << endl; } A(const A& src): _a(src._a) { cout << "A(const A& src)"<< this << endl; } ~A() { cout << "~A()"<< this <<endl; } }; class B : public A { private: int _b; public: B(int b): _b(b), A() { cout << "B()" << this << endl; } B(const B& src): _b(src._b) { cout << "B(const B& src)" << this << endl; } ~B() { cout << "~B()"<< this <<endl; } };
結論:
1.先調用基類缺省的構造函數,後調用派生類的拷貝構造函數
2.若派生類沒有缺省構造函數A(),就會報錯
疑惑:如何去調用基類的拷貝構造而不是缺省構造
#include<iostream> using namespace std; class A { private: int _a; public: A(int a = 0) : _a(a) { cout << "A()" << this << endl; } A(const A& src) : _a(src._a) { cout << "A(const A& src)" << this << endl; } ~A() { cout << "~A()" << this << endl; } }; class B : public A { private: int _b; public: B(int b) : _b(b), A() { cout << "B()" << this << endl; } B(const B& src) : _b(src._b), A(src) //發生賦值兼容規則(切片) { cout << "B(const B& src)" << this << endl; } ~B() { cout << "~B()" << this << endl; } }; int main() { B b(10); B b1(b); return 0; }
結果:
將B類型src傳遞給A類型的A(const A& src)拷貝構造函數,發生瞭賦值兼容規則(切片現象)
三、賦值重載不具有繼承性
#include<iostream> using namespace std; class A { private: int _a; public: A(int a = 0) : _a(a) { cout << "A()" << this << endl; } A(const A& src) : _a(src._a) { cout << "A(const A& src)" << this << endl; } A& operator=(const A& src) { if(this != &src) { _a = src._a; cout << "A& operator=(const A& src)" << endl; } } ~A() { cout << "~A()" << this << endl; } }; class B : public A { private: int _b; public: B(int b) : _b(b), A() { cout << "B()" << this << endl; } B(const B& src) : _b(src._b), A(src) //發生賦值兼容規則(切片) { cout << "B(const B& src)" << this << endl; } B& operator=(const B& src) { if(this != &src) { _b = src._b; cout << "B& operator=(const B& src)" << endl; } } ~B() { cout << "~B()" << this << endl; } }; int main() { B b1(10); B b2(20); b1 = b2; return 0; }
結論:默認情況下僅僅調用瞭派生類的對象的賦值重載,並未調用基類的賦值重載。
解決方案:
#include<iostream> using namespace std; class A { private: int _a; public: A(int a = 0) : _a(a) { cout << "A()" << this << endl; } A(const A& src) : _a(src._a) { cout << "A(const A& src)" << this << endl; } A& operator=(const A& src) { if(this != &src) { _a = src._a; cout << "A& operator=(const A& src)" << endl; } } ~A() { cout << "~A()" << this << endl; } }; class B : public A { private: int _b; public: B(int b) : _b(b), A() { cout << "B()" << this << endl; } B(const B& src) : _b(src._b), A(src) //發生賦值兼容規則(切片) { cout << "B(const B& src)" << this << endl; } B& operator=(const B& src) { if(this != &src) { *(A*)this = src; //將調用基類賦值重載 _b = src._b; cout << "B& operator=(const B& src)" << endl; } } ~B() { cout << "~B()" << this << endl; } }; int main() { B b1(10); B b2(20); b1 = b2; return 0; }
總結
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!