什麼時候需要複製建構函式? 複製建構函式是實現乙個類所必不可少的嗎? 同問,什麼時候需要過載賦值操作符? 賦值操作符過載是否必須實現?
#ifndef string_h_
#define string_h_
class string
;#endif
實現檔案string.cpp:
#include
"string.h"
#include
#include
using namespace std;
unsigned string:
:s_nobj =0;
string:
:string()
string:
:string
(const
char
*str)
string::~
string()
void string:
:print()
const
說明:
這個類宣告了乙個建構函式,函式形參為指向const的char指標.類成員m_pbuf為指向char型別的指標,在建構函式中,使用new操作符建立char記憶體塊,然後將傳進來的實參拷貝到m_pbuf.
隨後,使用print函式列印字串內容,注意,這個類在析構函式中釋放m_pbuf,以期在物件銷毀時釋放記憶體.
下面是使用這個類的main函式:
#include
#include
"string.h"
using namespace std;
void
show
(const string str)
;int
main()
return0;
}void
show
(const string str)
執行結果如下:
對程式執行結果的說明:
咋一看,程式執行結果輸出介面上除了我們自己列印的資訊之外,還多了一堆執行時錯誤資訊,其中最顯眼的資訊莫過於"double free or corruption"
,說明程式釋放了已經釋放了的記憶體.而從我們物件計數全域性變數s_nobj的列印資訊上看,物件計數溢位了,這更說明了析構函式被對用了多次,即delete與new呼叫的次數不匹配.
進一步跟蹤,發現我們實現的建構函式列印的資訊次數和析構函式列印的資訊並沒有成對出現.
原來,在我們實現類時,如果沒有提供一種叫做複製建構函式時,編譯器自動為我們生成預設的複製建構函式,其原型為
type_name &
type_name
(const type_name &obj)
;
預設的複製建構函式在函式體執行時,逐成員複製非指標和引用類的成員,而指標類的成員也將按值複製,即只簡單複製指標的位址,這樣就導致了目標物件的指標成員變成了指向源物件指標成員的指標,指向與源物件指標成員的同乙個記憶體塊.
但是,物件在銷毀時,都無一例額外的呼叫了析構函式,並且都執行了delete操作,多個物件試圖delete同乙個記憶體塊,系統出於資料的保護,這就丟擲了異常.
知道了問題根源,解決問題就容易得多了,那就是實現複製建構函式和過載賦值操作符,對指標成員進行深拷貝,新增複製建構函式和賦值操作符過載後的string類如下:
string.h
#ifndef string_h_
#define string_h_
class string
;#endif
string.cpp
#include
"string.h"
#include
#include
using namespace std;
unsigned string:
:s_nobj =0;
string:
:string()
string:
:string
(const
char
*str)
//實現複製建構函式
string:
:string
(const string &s)
string::~
string()
//實現賦值操作符過載
string &string:
:operator=
(const string &s)
delete [
]m_pbuf;
size_t sz =
strlen
(s.m_pbuf)
; m_pbuf = new char
[sz+1]
;strcpy
(m_pbuf, s.m_pbuf)
;return
*this;
}void string:
:print()
const
如果類中宣告了指標成員,則必須實現複製建構函式和過載賦值操作符,否則很有可能因為在複製物件或進行物件賦值時,由於物件析構導致兩次釋放記憶體,進而程式崩潰(視編譯器而定). C 複製建構函式
c 複製建構函式,一般在一下幾種情況中出現 1 物件以值傳遞的方式傳入函式時 2 物件以值傳遞的的方式從函式返回 3 乙個物件通過另乙個物件初始化 4 陣列 根據陣列中的初始化列表初始化陣列的時候。5 容器 初始化順序容器中的元素 有3種情況必須使用複製建構函式 a 如果有資料成員是指標 b 要在建...
C 複製建構函式
1.概念 只有單個形參,而且該形參是對本類型別物件的引用 常用const修飾 2.首先看乙個小例子 h中 class test private int a float b cpp中 int main test test1 5,5.5 test test2 1,1.1 coutcouttest3使用了...
C 複製建構函式
誰知道 include include using namespace std class person 如果兩種方式同時存在,會呼叫沒有const的版本 2.推薦,存在唯一的person person person person 3.不推薦,這個依然是複製建構函式,詭異。與第二種方法存在二義性 p...