賦值運算子
析構函式
總結構造、拷貝、賦值、析構函式是類的四個特殊成員函式,其特殊之處在於,即使我們沒有定義這些函式,編譯器也會自動提供預設函式,但如果我們提供了這些函式的顯式定義,那麼編譯器將不會再提供。這可能導致一些隱藏的問題,因此,我們需要對他們的實現進行充分的認識。
假定有乙個類klunk,那麼其預設建構函式定義如下:
klunk::
klunk()
編譯器為我們提供了乙個不接受任何引數,也不執行任何操作的建構函式,我們可以像下面這樣呼叫:
klunk lunk;
但是這種不做任何操作的建構函式也許並不是我們需要的,那麼我們就可以顯式定義預設建構函式,如下:
klunk::
klunk()
複製建構函式用於將乙個物件複製到新建立的物件中,它接收乙個指向類物件的常量引用作為引數,形式如下:
string
(const string&
);
以下情形都會呼叫複製建構函式:
值得注意的是,即使我們呼叫賦值運算子,也會呼叫拷貝建構函式。
預設複製建構函式在複製過程中,會將成員的值進行逐個拷貝;如果成員中也有類成員存在,那麼也將遞迴拷貝。但是需要注意的是,以上過程都是一種淺拷貝,這在碰到指標時將會帶來災難:建立了乙個新的指標指向原指標指向的位址,而沒有額外分配新的空間。這將導致:兩個物件中都包含了指向同一位址的指標,在進行析構時,可能導致程式異常。
因此,我們需要深拷貝,與淺拷貝不同,深拷貝在進行複製時將會額外為指標指向額外分配新的空間,然後再進行值拷貝。如下所示:
string ::
string
(const string& st)
賦值運算子接收乙個指向類物件的常量引用作為引數,而返回乙個指向類物件的引用。形式如下:
string & string::
operator=(
const string&
);
賦值運算子和複製拷貝類似,也是逐個拷貝,因此,也需要注意淺拷貝帶來的問題。所以大多數時候需要我們實現自定義的複製運算子,在實現過程中,我們需要注意以下幾個問題:
析構函式,不必再作過多介紹,我們主要用它釋放動態分配的記憶體。
綜上所述,我們可以完成乙個類的基本實現了,以自定義string類為例,**如下:
class
string
;string::
string
(const
char
*str)
else
}string::
string
(const string &str)
string &string::
operator=(
const string &str)
類的構造 析構 拷貝 賦值函式
讀 高質量程式設計指南 chapter 14總結 一般情況下,對於任意乙個類a,如果不顯示的宣告和定義,會自動生成預設的4個public inline函式 class a 1,初始化和賦值的區別 初始化是在建立物件時使用初始值直接填充物件的記憶體單元,因此不會有資料型別轉換,也不會產生臨時物件。而賦...
c 建構函式 拷貝,賦值,析構
建構函式 可以參考 作用 為物件成員變數賦初始值。new運算子一起使用 注意 1.建構函式的命名必須和類名完全相同 2.沒有返回值,即不用在定義時加返回值型別 void int float之類的 3.建構函式不能被直接呼叫,必須通過new運算子在建立物件時才會自動呼叫 拷貝函式 可自定義 思路就是賦...
建構函式,拷貝建構函式,析構函式,賦值函式
class cgoods else mamount amount mprice price cgoods 析構函式 cgoods const cgoods src 拷貝建構函式 void operator const cgoods src 賦值函式 private char mpname int m...