1-題目
:
下面是乙個陣列類的宣告與實現;請分析這個類有什麼問題,並針對存在的問題提出幾種解決方案。
//有問題的**
template class arr
}~arr()
}void setvalue(unsigned index, const t &value)
}t getvalue(unsigned index) const
else
}private:
t* data;
unsigned size;
};
2-思路
:
軟體存在的大部分問題通常都可以歸結指標的不正確處理
。這個類只提供了乙個建構函式,而沒有定義構造拷貝函式
和過載拷貝運算子函式
。
當按下面的方式宣告並例項化該類的乙個例項 :arr a(10); arr b(a);
,或者按下面的方式把該類的乙個例項賦值給另外乙個例項 :arr a(10); arr b(10); b=a;
,編譯器將呼叫其自動生成
的構造拷貝函式或者拷貝運算子的過載函式,預設是對指標實行按位拷貝
,僅僅只是拷貝指標的位址,而不會拷貝指標的內容。
因此在執行完前面的**之後,a.data和b.data指向的是同一位址
。當a或者b中任意乙個結束其生命週期呼叫析構函式時,會刪除data。由於他們的data指向的是同乙個地方,兩個例項的data都被刪除了。但另乙個例項並不知道它的data已經被刪除了
,當企圖再次用它的data的時候,程式就會不可避免地崩潰。
2.1-方案1
: 由於問題出現的根源是呼叫了編譯器生成的預設構造拷貝函式和拷貝運算子的過載函式。乙個最簡單的辦法就是禁止使用這兩個函式。於是可以把這兩個函式宣告為私有函式,如果類的使用者企圖呼叫這兩個函式,將不能通過編譯。實現的**如下 :
private:
arr(const arr& copy);
const arr& operator = (const arr& copy);
2.2-方案2
: 最初的**存在問題是因為不同例項的data指向的同一位址,刪除乙個例項的data會把另外乙個例項的data也同時刪除。因此我們還可以讓構造拷貝函式或者拷貝運算子的過載函式拷貝的不只是位址,而是資料。由於我們重新儲存了乙份資料,這樣乙個例項刪除的時候,對另外乙個例項沒有影響。這種思路我們稱之為深度拷貝
。實現的**如下 :
public:
arr(const arr ©) : data(0), size(copy.size)}}
const arr &operator=(const arr ©)
size = copy.size;
if (size > 0)
}}
2.3-方案3
: 為了防止有多個指標指向的資料被多次刪除,我們還可以儲存究竟有多少個指標指向該資料,只有當沒有任何指標指向該資料的時候才可以被刪除,這種思路通常被稱之為引用計數技術
。在建構函式中,引用計數初始化為1
;每當把這個例項賦值給其他例項或者以引數傳給其他例項的構造拷貝函式的時候,引用計數加1
,因為這意味著又多了乙個例項指向它的data;每次需要呼叫析構函式或者需要把data賦值為其他資料的時候,引用計數要減1
,因為這意味著指向它的data的指標少了乙個。當引用計數減少到0的時候,data已經沒有任何例項指向它了,這個時候就可以安全地刪除。實現的**如下 :
public:
arr(unsigned arrsize) : data(0), size(arrsize), count(new unsigned int)
}arr(const arr ©) : size(copy.size), data(copy.data), count(copy.count)
~arr()
const arr &operator=(const arr ©)
release();
data = copy.data;
size = copy.size;
count = copy.count;
(*count)++;
}private:
void release()
delete count;
count = 0;}}
unsigned int *count;
程式設計師面試題精選 15 含有指標成員的類的拷貝
題目 下面是乙個陣列類的宣告與實現。請分析這個類有什麼問題,並針對存在的問題提出幾種解決方案。templateclass array array void setvalue unsigned index,const t value t getvalue unsigned index const pr...
程式設計師面試題精選 15 含有指標成員的類的拷貝
題目 下面是乙個陣列類的宣告與實現。請分析這個類有什麼問題,並針對存在的問題提出幾種解決方案。c template typenamet classarray array voidsetvalue unsigned index,constt value t getvalue unsigned inde...
程式設計師面試一百題 05 查詢最小的k個元素
1 題目 輸入n個整數,輸出其中最小的k個。2 示例 輸入1,2,3,4,5,6,7,8八個數,則最小的4個數為1,2,3,4。3 思路 3.1 最簡單的思路就是將n個數排序,然後取出最小的k個數,但是這樣的時間複雜度為o n logn 3.2 我們嘗試更快的思路。可以開闢乙個長度為k的陣列karr...