題目:下面是乙個陣列類的宣告與實現。請分析這個類有什麼問題,並針對存在的問題提出幾種解決方案。
1 templateclassarray29
10 ~array()
1114
15void setvalue(unsigned index, const t&value)
1620
21 t getvalue(unsigned index) const
2228
29private
:30 t*data;
31unsigned size;
32 };
分析:我們注意在類的內部封裝了用來儲存陣列資料的指標。軟體存在的大部分問題通常都可以歸結指標的不正確處理。
這個類只提供了乙個建構函式,而沒有定義構造拷貝函式和過載拷貝運算子函式。當這個類的使用者按照下面的方式宣告並例項化該類的乙個例項
array a(10);
array b(a);
或者按照下面的方式把該類的乙個例項賦值給另外乙個例項
array a(10);
array b(10);
b=a;
編譯器將呼叫其自動生成的構造拷貝函式或者拷貝運算子的過載函式。在編譯器生成的預設的構造拷貝函式和拷貝運算子的過載函式,對指標實行的是按位拷貝,僅僅只是拷貝指標的位址,而不會拷貝指標的內容。因此在執行完前面的**之後,a.data和b.data指向的同一位址。當a或者b中任意乙個結束其生命週期呼叫析構函式時,會刪除data。由於他們的data指向的是同乙個地方,兩個例項的data都被刪除了。但另外乙個例項並不知道它的data已經被刪除了,當企圖再次用它的data的時候,程式就會不可避免地崩潰。
由於問題出現的根源是呼叫了編譯器生成的預設構造拷貝函式和拷貝運算子的過載函式。乙個最簡單的辦法就是禁止使用這兩個函式。於是我們可以把這兩個函式宣告為私有函式,如果類的使用者企圖呼叫這兩個函式,將不能通過編譯。實現的**如下:
1private
:2 array(const array©);
3const array& operator = (const array& copy);
最初的**存在問題是因為不同例項的
data
指向的同一位址,刪除乙個例項的
data
會把另外乙個例項的
data
也同時刪除。因此我們還可以讓構造拷貝函式或者拷貝運算子的過載函式拷貝的不只是位址,而是資料。由於我們重新儲存了乙份資料,這樣乙個例項刪除的時候,對另外乙個例項沒有影響。這種思路我們稱之為深度拷貝。實現的**如下:
1public
:2 array(const array& copy):data(0
), size(copy.size)310
}1112const array& operator = (const array©)
1322
23 size =copy.size;
24if(size > 0)25
30 }
為了防止有多個指標指向的資料被多次刪除,我們還可以儲存究竟有多少個指標指向該資料。只有當沒有任何指標指向該資料的時候才可以被刪除。這種思路通常被稱之為引用計數技術。在建構函式中,引用計數初始化為
1;每當把這個例項賦值給其他例項或者以引數傳給其他例項的構造拷貝函式的時候,引用計數加
1,因為這意味著又多了乙個例項指向它的
data
;每次需要呼叫析構函式或者需要把
data
賦值為其他資料的時候,引用計數要減
1,因為這意味著指向它的
data
的指標少了乙個。當引用計數減少到
0的時候,
data
已經沒有任何例項指向它了,這個時候就可以安全地刪除。實現的**如下:
1public:2
array(unsigned arraysize)
3 :data(0), size(arraysize), count(new unsigned int)4
910 array(const array©)
11: size(copy.size), data(copy.data), count(copy.count)
1215
16 ~array()
1720
21const array& operator = (const array©)
2233
34private:35
void
release()
3645
46delete count;
47 count = 0;48
}49}50
51 unsigned int *count;
**何海濤部落格
含有指標成員的類的拷貝
題目 下面是乙個陣列類的宣告與實現。請分析這個類有什麼問題,並針對存在的問題提出幾種解決方案。template class array array voidsetvalue unsigned index,const t value t getvalue unsignedindex const pri...
關於含有指標成員的類的物件之間賦值指標的問題。
在c 中,當定義了乙個類,類的成員中有指標的時候,需要注意 如果將類的物件a賦值給b的時候,兩個物件的指標是指向同乙個位址的,其餘的變數都是相等的。在影象處理中,比如定義了乙個影象類,類成員中有具體的影象資料,如果將兩個物件直接相等,會使兩個物件的資料指標指向同乙個位址。如果要使兩個物件的指向不同的...
函式返回含有指標成員的物件
移動構造 淺層複製只實現物件間的資料元素一一對應,只複製成員函式中的指標位址,如下圖 pointarray2複製了pointarray1,只複製了指標,pointarray2與pointarray1指向了同一塊陣列元素,在執行後進行記憶體釋放時會先呼叫pointarray1的析構函式釋放陣列記憶體,...