程式設計師面試題精選 15 含有指標成員的類的拷貝

2021-08-30 04:06:02 字數 1859 閱讀 9178

題目:下面是乙個陣列類的宣告與實現。請分析這個類有什麼問題,並針對存在的問題提出幾種解決方案。

templateclass array

~array()

void setvalue(unsigned index, const t& value)

t getvalue(unsigned index) const

private:

t* data;

unsigned size;

};

分析:我們注意在類的內部封裝了用來儲存陣列資料的指標。軟體存在的大部分問題通常都可以歸結指標的不正確處理。

這個類只提供了乙個建構函式,而沒有定義構造拷貝函式和過載拷貝運算子函式。當這個類的使用者按照下面的方式宣告並例項化該類的乙個例項

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的時候,程式就會不可避免地崩潰。

由於問題出現的根源是呼叫了編譯器生成的預設構造拷貝函式和拷貝運算子的過載函式。乙個最簡單的辦法就是禁止使用這兩個函式。於是我們可以把這兩個函式宣告為私有函式,如果類的使用者企圖呼叫這兩個函式,將不能通過編譯。實現的**如下:

private:

array(const array& copy);

const array& operator = (const array& copy);

最初的**存在問題是因為不同例項的data指向的同一位址,刪除乙個例項的data會把另外乙個例項的data也同時刪除。因此我們還可以讓構造拷貝函式或者拷貝運算子的過載函式拷貝的不只是位址,而是資料。由於我們重新儲存了乙份資料,這樣乙個例項刪除的時候,對另外乙個例項沒有影響。這種思路我們稱之為深度拷貝。實現的**如下:

為了防止有多個指標指向的資料被多次刪除,我們還可以儲存究竟有多少個指標指向該資料。只有當沒有任何指標指向該資料的時候才可以被刪除。這種思路通常被稱之為引用計數技術。在建構函式中,引用計數初始化為1;每當把這個例項賦值給其他例項或者以引數傳給其他例項的構造拷貝函式的時候,引用計數加1,因為這意味著又多了乙個例項指向它的data;每次需要呼叫析構函式或者需要把data賦值為其他資料的時候,引用計數要減1,因為這意味著指向它的data的指標少了乙個。當引用計數減少到0的時候,data已經沒有任何例項指向它了,這個時候就可以安全地刪除。實現的**如下:

public:

array(unsigned arraysize)

:data(0), size(arraysize), count(new unsigned int)

array(const array& copy)

: size(copy.size), data(copy.data), count(copy.count)

~array()

const array& operator = (const array& copy)

private:

void release()

delete count;

count = 0;}}

unsigned int *count;

程式設計師面試題精選 15 含有指標成員的類的拷貝

題目 下面是乙個陣列類的宣告與實現。請分析這個類有什麼問題,並針對存在的問題提出幾種解決方案。c template typenamet classarray array voidsetvalue unsigned index,constt value t getvalue unsigned inde...

程式設計師面試題精選

問題描述 輸入乙個字串,列印出該字串中字元的所有排列。例如輸入字串abc,則輸出由字元a b c所能排列出來的所有字串abc acb bac bca cab和cba。問題分析 這是一道很好的考查對遞迴理解的程式設計題。寫遞迴程式關鍵有兩點,處理好進入與返回的關係,進入時改變了什麼,返回時應當恢復。字...

程式設計師面試題精選100題

今天開始各種刷面試題,沉下心來集中時間,全身心投入 題目 輸入一棵二元查詢樹,將該二元查詢樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只調整指標的指向。比如將二元查詢樹 10 6 14 4 8 12 16 轉換成雙向鍊錶 4 6 8 10 12 14 16。相關概念 二元查詢樹 它首先要是...