以下摘自林銳的高質量c++程式設計:
如果不主動編寫拷貝建構函式和賦值函式,編譯器將以「位拷貝」的方式自動生成預設的函式。倘若類中含有指標變數,那麼這兩個預設的函式就隱含了錯誤。以類string 的兩個物件a,b 為例,假設a.m_data 的內容為「hello」,b.m_data 的內容為「world」。
現將a 賦給b,預設賦值函式的「位拷貝」意味著執行b.m_data = a.m_data。這將造成三個錯誤:一是b.m_data 原有的記憶體沒被釋放,造成記憶體洩露;二是b.m_data 和a.m_data 指向同一塊記憶體,a 或b 任何一方變動都會影響另一方;三是在物件被析構時,m_data 被釋放了兩次。
**如下:
#ifndef string_h_
#define string_h_
#include #include using namespace std;
class string
string(const char* str)
:data_(new char[strlen(str)+1])
void set_data(const char* str)
}void output_data(void)
~string()
friend ostream& operator <<(ostream& os, const string &str);
private:
char *data_;
};ostream& operator <<(ostream& os, const string &str)
#endif /* string_h_ */
#include #include "string.h"
using namespace std;
int main()
在g++下編譯時,會在輸出後顯示:aborted(core dumped)。輸出:
the string a is: hello
the string b is: hello
the string a is: world
the string b is: world
由string b的data_也是'world'說明:a 和 b的data_占用了同一塊記憶體,是位拷貝。
正確的string類,包含自定義的複製建構函式和賦值操作符:
#ifndef string_h_
#define string_h_
#include #include using namespace std;
class string
string(const char* str)
:data_(new char[strlen(str)+1])
//copy constructor
string(const string &str)
//operator =
string & operator =(string &str)
void set_data(const char* str)
}void output_data(void)
~string()
friend ostream& operator <<(ostream& os, const string &str);
private:
char *data_;
};ostream& operator <<(ostream& os, const string &str)
#endif /* string_h_ */
執行main函式的輸出:
the string a is: hello
the string b is: hello
the string a is: world
the string b is: hello
拷貝建構函式(複製建構函式)
執行 物件a 物件b時,系統需要呼叫拷貝建構函式,如果程式設計師沒寫,則呼叫預設的拷貝建構函式。預設的拷貝建構函式利用淺拷貝方式,它的樣子是 a const a a 淺拷貝 拷貝的時候,兩個指標指向同乙個區域 char str1 helloworld char str2 str1 深拷貝 拷貝的時候...
c 複製 拷貝建構函式
在c 中,定義乙個空類時,編譯器會預設宣告6個成員函式,它們分別是 class empty 注意 一下,編譯器預設合成的析構函式不是虛函式。首先,說一下什麼是拷貝建構函式 也可以叫複製建構函式 它是乙個特殊的建構函式,具有單個形參 此形參是對該類型別的引用,需要用const修飾,否則會無限迴圈呼叫複...
c 拷貝(複製)建構函式
class line line line const line obj 拷貝建構函式是一種特殊的建構函式,它在建立物件時,是使用同一類中之前建立的物件來初始化新建立的物件。拷貝建構函式通常用於 1 通過使用另乙個同型別的物件來初始化新建立的物件,即用已有物件給新建立物件賦值。line line1 1...