第十九篇:複製控制( 下 ) --- 自定義解構函式

穆晨發表於2017-01-26

前言

       經過前兩篇隨筆( 上  中 )的分析我們已經解決了具有指標成員的同類物件“ 干涉 ”問題。可惜,前面給出的解決方案程式碼還是不完整。還有什麼問題呢?觀察發現,建構函式裡面有new的關鍵字出現,也就是說開闢了新的記憶體空間,我們也知道new必須也只能對應一個delete,而不應該讓系統自己處理( 還不熟練new和delete用法的點這裡 ),但這裡和new對應的delete去哪裡了?

解決思路

       應該何時delete?顯然,應該在物件銷燬的時候delete。C++中定義了這樣一種函式 --- 解構函式,它與建構函式相對應,能在物件被銷燬時自動執行。

對【複製控制( 中 )解決方案】的改進

       下面的程式碼對【複製控制( 中 )解決方案】進行了進一步的改進 --- 設定了自定義的解構函式。至此,複製控制已經完全實現,我們可以正確效率地實現物件( 不論有無指標成員 )間的複製功能了:

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <fstream>
 4 #include <string>
 5 
 6 using namespace std;
 7 
 8 class A {
 9 public:
10     // 建構函式為指標成員開闢空間並賦初值0
11     A() {
12         num_p = new int;
13         *num_p = 0;
14     }
15     // 自定義複製函式 
16     A(const A & a) {
17         num_p = new int;
18         *num_p = a.getNum();
19     }
20     // 自定義賦值運算子號
21     A & operator=(const A & a) {
22         num_p = new int;
23         *num_p = a.getNum();
24     }
25     // 自定義解構函式
26     ~A() {
27         delete num_p;
28     cout << "物件正常銷燬" << endl;
29     }
30     // 給指標所指物件賦值
31     void setNum(int num) {
32         *num_p = num;
33     }    
34     // 獲取指標所指物件
35     int getNum() const {
36         int num = *num_p;
37         return num;
38     }
39 private:
40     int *num_p;
41 };
42 
43 int main()
44 {
45     A a1, a3;
46 
47     // 設定a1指標成員所指物件的值
48     a1.setNum(1);
49     // 呼叫自定義的複製函式
50     A a2=a1;
51     // 啟用自定義的賦值運算子
52     a3 = a1;
53     // 觀察得出a1,a2, a3的指標成員所指物件均為整數1。
54     cout << "a1`s num: " << a1.getNum() << endl;
55     cout << "a2`s num: " << a2.getNum() << endl;
56     cout << "a3`s num: " << a3.getNum() << endl;
57 
58     // 修改a1指標成員所指物件的值
59     a1.setNum(2);
60     // 觀察得出a1的指標成員所指物件改了,a2, a3的沒變。 
61     cout << "a1`s num: " << a1.getNum() << endl; 
62     cout << "a2`s num: " << a2.getNum() << endl;
63     cout << "a3`s num: " << a3.getNum() << endl;
64 
65     return 0;
66 }

       執行結果:

       

       觀察發現每個物件都使用了自定義的解構函式。

說明

       一個有用的經驗法則:如果類需要解構函式,它同時也需要自定義複製函式,過載賦值運算子。( 這就是C++中著名的“ 三法則 ” )

相關文章