歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C++構造函數和拷貝構造函數詳解

C++構造函數和拷貝構造函數詳解

日期:2017/3/1 10:30:42   编辑:Linux編程

構造函數、析構函數與賦值函數是每個類最基本的函數。它們太普通以致讓人容易麻痺大意,其實這些貌似簡單的函數就象沒有頂蓋的下水道那樣危險。

每個類只有一個析構函數和一個賦值函數,但可以有多個構造函數(包含一個拷貝構造函數,其它的稱為普通構造函數)。

對於任意一個類A,如果不想編寫上述函數,C++編譯器將自動為A 產生四個缺省的函數,例如:

A(void); // 缺省的無參數構造函數

A(const A &a); // 缺省的拷貝構造函數

~A(void); // 缺省的析構函數

A & operate =(const A &a); // 缺省的賦值函數

這不禁讓人疑惑,既然能自動生成函數,為什麼還要程序員編寫?原因如下:

<1>如果使用“缺省的無參數構造函數”和“缺省的析構函數”,等於放棄了自主“初始化”和“清除”的機會,C++發明人Stroustrup 的好心好意白費了。

<2>“缺省的拷貝構造函數”和“缺省的賦值函數”均采用“位拷貝”而非“值拷貝”的方式來實現,倘若類中含有指針變量,這兩個函數注定將出錯。

C++ 默認構造函數 :

1、每個類必須有一個構造函數,否則沒法創建對象;

2、若 程序員沒有提供任何構造函數,則 C++提供一個默認的構造函數,該默認構造函數是無參構造函數,它僅負責創建對象,不做任何初始化的工作;

3、只要 programer 定義了一個構造函數(不管是無參還是有參構造),C++就不再提供默認的默認構造函數。即如果為類定義了一個帶參的構造函數,還想要無參構造函數,就必須自己定義;

4、與變量定義類似,在用默認構造函數創建對象時,如果創建的是全局對象或靜態對象,則對象的位模式全為 0,否則,對象值是隨機的。

C++默認拷貝構造函數:

1、默認的拷貝構造函數執行的順序與其他用戶定義的構造函數相同,執行先父類後子類的構造.

2、拷貝構造函數對類中每一個數據成員執行成員拷貝(memberwise Copy)的動作.

3、如果數據成員為某一個類的實例,那麼調用此類的拷貝構造函數.

4、如果數據成員是一個數組,對數組的每一個執行按位拷貝.

5、如果數據成員是一個數量,如int,double,那麼調用系統內建的賦值運算符對其進行賦值.

請看下面代碼:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4. class Student
  5. {
  6. public:
  7. Student()
  8. {
  9. cout << "構造函數1" << endl;
  10. }
  11. Student(int k)
  12. {
  13. cout << "構造函數2" << endl;
  14. i = k;
  15. }
  16. Student(Student const &m)
  17. {
  18. cout << "拷貝構造函數" << endl;
  19. i = m.i * (-1);
  20. }
  21. void p()
  22. {
  23. cout << i << endl;
  24. }
  25. ~Student()
  26. {
  27. cout << "析構函數" << endl;
  28. }
  29. protected:
  30. int i;
  31. };
  32. int main(int argc, char **argv)
  33. {
  34. Student s(9818);
  35. // 調用構造函數2
  36. s.p();
  37. Student t(s);
  38. // 調用拷貝構造函數
  39. t.p();
  40. Student k = s;
  41. // 調用拷貝構造函數
  42. k.p();
  43. Student *p = new Student(s);
  44. // 調用拷貝構造函數
  45. p->p();
  46. Student m;
  47. // 調用構造函數1
  48. m = s;// 賦值運算
  49. m.p();
  50. return 0;
  51. }

運行結果:

  1. 構造函數2
  2. 9818
  3. 拷貝構造函數
  4. -9818
  5. 拷貝構造函數
  6. -9818
  7. 拷貝構造函數
  8. -9818
  9. 構造函數1
  10. 9818
  11. 析構函數
  12. 析構函數
  13. 析構函數
  14. 析構函數
Copyright © Linux教程網 All Rights Reserved