關於string類的深淺拷貝問題

2021-07-29 17:05:47 字數 1757 閱讀 1174

首先,先看一下下面的**會出現什麼問題?

class string

else

}~string() }

string(const string& s)

:_data(s._data)

{}private:

char* _data;

};void test()

上面的程式會奔潰,讓我們來分析原因:

這就是所謂的淺拷貝,也稱位拷貝,編譯器只是直接將指標的值拷貝過來,結果多個物件共用同一塊記憶體,當乙個物件將這塊記憶體釋放掉之後,另一些物件不知道該塊空間已經還給了系統,以為還有效,所以在對這段記憶體進行操作的時候,發生了訪問違規。

為了解決這個問題,我們引入深拷貝。

string::string(const string& s)//深拷貝

:_data(new char[strlen(s._data) + 1])

上面**則是str2,重新開闢了一塊空間,並將str1裡的值拷貝到str2這塊空間中。

深拷貝中賦值運算子的過載: 

下面有兩種方法,我們來看看哪種方法比較。

方法一:

string& operator=(const string&s)

return *this;

}

方法二:

string& operator=(const string&s)

return *this;

}

一般情況下,兩種方法都可以,但第二種方法更優一些。

方法一中,先將舊的空間釋放掉,然後又重新開闢出與形參同樣大小新的空間,然後將形參的內容拷貝到此空間,此方法有乙個弊端,就是當空間申請失敗時,不僅沒有成功賦值,也破壞了原有被賦值的物件。

方法二中,先開闢出新空間,將這個新空間賦值給tmp這個臨時變數,就算開闢失敗也不會破壞原有的物件。

最後還有一點,就是這裡的返回值是為了支援鏈式訪問。

下面就是面試中string類深拷貝的寫法,一般沒有特殊要求,將必要的成員的成員函式給出就可以了。

class string

else

}~string() }

string(const string& s)

:_data(new char[strlen(s._data)+1])

string& operator=(const string&s)

return *this;

}private:

char* _data;

};

拷貝建構函式的現**法:

string(const string& s)

:_data(null)

賦值運算子過載函式的兩種現**法:

string& operator=(const string&s)

string& operator=(const string&s)

return *this;//為了支援鏈式訪問

}

兩種寫法不同的是,第乙個的拷貝建構函式是在引數列表中完成的,第二種是在函式體內完成的。

以上是關於string類的深淺拷貝問題,當然在面試中也可以寫現**法。

String類與深淺拷貝

1 概念 被複製物件的所有變數都含有與原來的物件相同的值,而所有的對其他物件的引用仍然指向原來的物件。換言之,淺拷貝僅僅複製所考慮的物件,而不是複製它所引用的物件。2 舉例 class string else string const string s string operator const s...

string類的深淺拷貝問題

字串是我們在編寫程式的時候經常用的到的。c 庫已經幫我們實現了乙個功能更加強大的字串類string,我們要去了解它是怎麼實現的。只要是涉及到 string類的地方多少都會涉及到深淺拷貝的問題。在c 中,在用乙個物件初始化另乙個物件時,只複製了成員,並沒有複製資源,使兩個物件同時指向了同一資源的複製方...

面試題一 string類的深淺拷貝

pragma once include using namespace std 淺拷貝 析構物件時會出錯 class cmystring else 拷貝建構函式 cmystring const cmystring str m pdata null 析構函式 cmystring 賦值運算子過載 cmy...