首先大家看下以下string類的實現是否有問題?
class
string
_str =
newchar
[strlen
(str)+1
];strcpy
(_str, str);}
~string()
};// 測試
上述string類沒有顯式定義其拷貝建構函式與賦值運算子過載,此時編譯器會合成預設的,當用s1構造s2時,編譯器會呼叫預設的拷貝構造。最終導致的問題是,s1、s2共用同一塊記憶體空間,在釋放時同一塊空間被釋放多次而引起程式崩潰,這種拷貝方式,稱為淺拷貝。
淺拷貝:也稱位拷貝,編譯器只是將物件中的值拷貝過來。如果物件中管理資源,最後就會導致多個物件共享同乙份資源,當乙個物件銷毀時就會將該資源釋放掉,而此時另一些物件不知道該資源已經被釋放,以為還有效,所以當繼續對資源進項操作時,就會發生發生了訪問違規。
要解決淺拷貝問題,c++中引入了深拷貝。
如果乙個類中涉及到資源的管理,其拷貝建構函式、賦值運算子過載以及析構函式必須要顯式給出。一般情況都是按照深拷貝方式提供。
])// const 是因為對 s 不需要修改,安全性更高
// 引數 & 是因為不需要傳值拷貝、效率高
// 返回值 & 是為了連續賦值(效率高)
string&
operator=(
const string& s)
return
*this;}
~string()}};
測試**:
void
teststring()
intmain()
以下**是否完全正確,執行可能得到的結果是____。
classa;
classb~
b()}
;void
sayhello
(b b)
intmain()
a. 程式正常執行
b. 程式編譯錯誤
c. 程式崩潰
d. 程式死迴圈
正確答案:c
答案解析:
形參傳遞析構指標兩次
以下三種情況需要用到拷貝函式:
乙個物件以值傳遞的方式傳入函式體;
乙個物件以值傳遞的方式從函式返回;
乙個物件需要通過另外乙個物件進行初始化。
本例中,在呼叫sayhello(b)時符合上面1. 的情況,因此會呼叫拷貝建構函式。由於類中未顯式宣告乙個拷貝建構函式,編譯器將會自動生成乙個預設的拷貝建構函式,來完成物件間的位拷貝(或稱淺拷貝),也就是把物件裡的值完全複製給另乙個物件,如classx = classy。這時,如果classy中有乙個成員變數指標已經申請了記憶體,那classx中的那個成員變數也指向同一塊記憶體。這就出現了問題:當classy把記憶體釋放了(如:析構),這時classx內的指標就是野指標了,出現執行錯誤。(即sayhello()函式體結束析構了一次,main()函式結束又一次析構,而這時p已經是野指標了,因而出錯。)
#include
using
namespace std;
class
myclass
myclass
(const myclass &x)
myclass &
operator=(
const myclass &x)
~myclass()
};intmain()
執行時的輸出結果是()
a. 11214444
b. 11314444
c. 122444
d. 123444
正確答案: c
答案解析
c d 辨析:
關鍵是區分 淺/深拷貝操作 和 賦值操作:
a a ;
a b;
a = b;
這裡是賦值操作。
a a;
a b = a;
這裡是淺拷貝操作。
a a ;
a b;
a = b;
這裡是深拷貝操作(當然這道題直接返回了,通常我們過載賦值運算子進行深拷貝操作)。
a a;
a b = a;
這裡還是淺拷貝操作。
所以 myclass obj3 = obj1; 呼叫的是拷貝建構函式。
如果寫成 myclass obj3; obj3 = obj1; 輸出的結果就是 123444
C string的深拷貝與淺拷貝
在c 中,基本所有的類都要考慮深拷貝,淺拷貝與寫時拷貝,根據不同的定義,選擇適合自己的拷貝方式。時間類就可以用淺拷貝,而二叉樹,string類就需要深拷貝。string類在vs編譯器下使用的深拷貝,在linux下使用的淺拷貝。為什麼會存在深淺拷貝的問題呢?string的淺拷貝是讓兩個不同的指標指向同...
String類,淺拷貝,深拷貝
想要使用c 中的類那麼必須要有它的標頭檔案,include 首先來看下面乙個 這個程式很簡單,但是如果有乙個空指標呢?那麼就需要判斷了,並且用預設值把有引數的string和沒有引數的string合併在一起,那這個程式只需要做下面的改變 既然你的建構函式開闢了一段空間,那麼就需要釋放掉,此時就需要析構...
C 深拷貝與淺拷貝(實現String類)
所謂淺拷貝,指的是在物件複製時,只是對物件中的資料成員進行簡單的複製,預設拷貝建構函式執行的也是淺拷貝。簡單的說,淺拷貝就是值傳遞,將源空間裡面的內容複製到目標空間中。存在缺陷 多個指標可能共用管理一塊記憶體空間,在釋放時,導致對一塊空間的多次釋放,造成記憶體洩露。在 深拷貝 的情況下,對於物件中動...