日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【C++ Primer 第15章】定义派生类拷贝构造函数、赋值运算符

發布時間:2025/5/22 c/c++ 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++ Primer 第15章】定义派生类拷贝构造函数、赋值运算符 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

學習資料

? 派生類的賦值運算符/賦值構造函數也必須處理它的基類成員的賦值

??C++ 基類構造函數帶參數的繼承方式及派生類的初始化

?

定義拷貝構造函數

【注意】對派生類進行拷貝構造時,如果想讓基類的成員也同時拷貝,就一定要在派生類拷貝構造函數初始化列表中顯示調用基類拷貝構造函數(當然在函數體內將基類部分的值拷貝也是可以的,只不過它是先用默認構造函數初始化后再修改的基類成員變量的值,效率比較低),否則它會調用基類的默認構造函數,而不會對基類的成員變量拷貝值,這樣生成的對象,它的派生類部分和被拷貝的對象派生類部分一樣,而基類部分則是默認構造函數的初始化結果。

代碼例子1:

1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 A() { cout << "A default constructor" << endl; } 8 A(A&) { cout << "A copy constructor" << endl; } 9 }; 10 class B : public A 11 { 12 public: 13 B() { cout << "A default constructor" << endl; } 14 B(B &b) { cout << "B copy constructor" << endl; } 15 }; 16 17 int main() 18 { 19 B b; 20 B c = b; 21 return 0; 22 }

輸出結果:

?

?

代碼例子2:

1 #include <iostream> 2 using namespace std; 3 4 class A 5 { 6 public: 7 A() { cout << "A default constructor" << endl; } 8 A(A&) { cout << "A copy constructor" << endl; } 9 }; 10 class B : public A 11 { 12 public: 13 B() { cout << "A default constructor" << endl; } 14 B(B &b) : A(b) { cout << "B copy constructor" << endl; } 15 }; 16 17 int main() 18 { 19 B b; 20 B c = b; 21 return 0; 22 }

輸出結果:

?

?

C++ 基類構造函數帶參數的繼承方式及派生類的初始化

在定義類的時候,會遇到基類的構造函數帶參數,而子類子類構造函數不帶參數,這時候如果以代碼 a 的方式建立派生類則會出錯。

1 class A 2 { 3 public: 4 A(int x, int y): i(x), j(y) {} 5 private: 6 int i, j; 7 }; 8 9 class B : public A 10 { 11 public: 12 B() { cout << "init B" << endl; } 13 };

在建立B類對象時,編譯出錯:?
?C:\Documents and Settings\admin\桌面\Text1.cpp(104) : error C2512: ‘A’ : no appropriate default constructor available?

?

解決這個問題應該在A的構造函數中顯式調用基類的帶參構造函數。因為在基類中定義了帶參構造函數,編譯器不會提供默認構造函數。(或者可以在基類中增加一個不帶參數的構造函數)這個問題將解決。?
代碼 b 采用的是調用基類帶參構造函數的方式:

代碼 b:

1 class A 2 { 3 public: 4 A(int x, int y): i(x), j(y) {} 5 private: 6 int i, j; 7 }; 8 9 class B : public A 10 { 11 public: 12 B() A(10,20) { cout << "init B" << endl; } 13 };

?

通過在基類中增加一個不帶參數的構造函數:?
代碼 c:

1 class A 2 { 3 public: 4 A(int x, int y): i(x), j(y) {} 5 A(); //不帶參數的構造函數 6 private: 7 int i, j; 8 }; 9 10 class B:public A 11 { 12 public: 13 B(): A(10,20) { cout << "init B" << endl; } 14 };

?

定義派生類賦值運算符

與拷貝和移動構造函數一樣,派生類的賦值運算符也必須為其基類部分賦值。

1 // Base::operator=(const Base&) 不會被自動調用 2 D& D::operator=(const D &rhs) 3 { 4 Base::operator=(rhs); //為基類部分賦值 5 //按照過去的方式為派生類的成員賦值 6 return *this; 7 }

?舉例說明:

1 class base 2 { 3 public: 4 base(int initialvalue = 0): x(initialvalue) {} 5 6 private: 7 int x; 8 }; 9 10 class derived : public base 11 { 12 public: 13 derived(int initialvalue): base(initialvalue), y(initialvalue) {} 14 derived& operator=(const derived& rhs); 15 16 private: 17 int y; 18 }; 19 20 邏輯上說,derived的賦值運算符應該象這樣: 21 derived& derived::operator = (const derived& rhs) // 錯誤的賦值運算符 22 { // 請注意d1的base部分沒有被賦值操作改變。 23 if (this == &rhs) 24 return *this; 25 y = rhs.y; 26 return *this; 27 } 28 29 不幸的是,它是錯誤的,因為derived對象的base部分的數據成員x在賦值運算符中未受影響。例如,考慮下面的代碼段: 30 31 void assignmenttester() 32 { 33 derived d1(0); // d1.x = 0, d1.y = 0 34 derived d2(1); // d2.x = 1, d2.y = 1 35 36 d1 = d2; // d1.x = 0, d1.y = 1 37 } 38 39 40 derived& derived::operator = (const derived& rhs) // 正確的賦值運算符 41 { 42 if (this == &rhs) 43 return *this; 44 45 base::operator = (rhs); // 調用this->base::operator= 46 y = rhs.y; 47 48 return *this; 49 }

?

轉載于:https://www.cnblogs.com/sunbines/p/9215310.html

總結

以上是生活随笔為你收集整理的【C++ Primer 第15章】定义派生类拷贝构造函数、赋值运算符的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。