在c++中,呼叫拷貝建構函式有三種情況:
1.乙個物件作為函式引數,以值傳遞的方式傳入函式體.
2.乙個物件作為函式返回值,以值傳遞的方式從函式返回.
3.乙個物件用於給另外乙個物件進行初始化(複製初始化).
拷貝建構函式必須以引用的形式傳遞(引數為引用值).其原因如下:
當乙個物件以傳遞值的方式傳乙個函式的時候,拷貝建構函式自動的呼叫來生成函式中的物件.
這樣會導致無限迴圈地呼叫拷貝建構函式,直至棧溢位.
以前,一直有個誤解,以為以同型別的物件呼叫"="時,就會呼叫賦值符.參看以下的例子:
1class
ctest ;
7ctest::ctest()
811 ctest::ctest(const ctest&arg)
1215 ctest& ctest::operator=(const ctest&arg)
1619
intmain()
20
按照以前的理解,第21~24行**,應該分別呼叫建構函式,拷貝建構函式,賦值符函式,賦值符函式.
然而最終如下,不是如自己所想...說明以前的理解是錯誤的.
constructor of ctestcopy constructor of ctest
copy constructor of ctest
assign function of ctest
第23行**呼叫的是拷貝建構函式,不是賦值符函式,但第24行**呼叫的賦值符函式,不是拷貝建構函式.原因如下:
拷貝建構函式建立新的物件,而賦值符函式不建立新物件,它要求"="的左右物件均已存在,它的作用就是把"="右邊的物件的值賦給左邊的物件.
雖然編譯器會提供拷貝建構函式和賦值符函式,但是有時候編譯器提供的這些函式,並不能滿足我們的需求,因而需要自定義拷貝建構函式和賦值函式.
這裡就會引出乙個新問題,什麼時候需要自定義拷貝建構函式和賦值符函式.
簡單的規則:如果需要定義乙個非空的析構函式,那麼,通常情況下也需要定義乙個拷貝建構函式和賦值符函式.
通常的原則是:
1.對於凡是包含動態分配成員或包含指標成員的類都應該提供拷貝建構函式;
2.在提供拷貝建構函式的同時,還應該考慮過載"="賦值操作符,即提供賦值符函式.
當我們知道需要自定義拷貝建構函式和賦值符函式時,就得考慮如何良好的實現它們.
當自定義copying函式(包含拷貝建構函式和賦值符函式)時,需要確保以下兩點:
1.複製所有的local成員變數
2.呼叫所有base classes內的適當的copying函式,完成基類的copying.
下面是乙個具體的例子:
1void logcall(const std::string& funcname); //
製造乙個log entry
2class
customer ;
11 customer::customer(const customer&rhs):name(rhs.name)
1215 customer& customer::operator=(const customer&rhs)
1621
22class prioritycustomer:public
customer ;
31 prioritycustomer::prioritycustomer(const prioritycustomer&rhs):customer(rhs),priority(rhs.priority)
3235 prioritycustomer& prioritycustomer::operator=(const prioritycustomer&rhs)
36
第18行**中,通過物件呼叫私有變數,似乎違背了私有變數的含義,有點無法理解,具體的分析和理解,請參考:
使用opertator=函式給物件賦值時,若右邊的物件和呼叫物件相同,即自我賦值,會引發自我賦值的不安全問題.具體分析和解決方案,請參考:
參考資料:
c 拷貝建構函式和賦值符函式
在c 中,呼叫拷貝建構函式有三種情況 1.乙個物件作為函式引數,以值傳遞的方式傳入函式體 2.乙個物件作為函式返回值,以值傳遞的方式從函式返回 3.乙個物件用於給另外乙個物件進行初始化 複製初始化 拷貝建構函式必須以引用的形式傳遞 引數為引用值 其原因如下 當乙個物件以傳遞值的方式傳乙個函式的時候,...
c 拷貝建構函式和賦值函式
準備實現gof上面乙個迭代器模式,用到了上面的list基本類,但是一直對賦值函式和拷貝建構函式不是很熟悉,就研讀了一下effective c 的關於這方面的一章,頗有收穫,抽取了我認為精華的部分分享給大家。由於一直對c 這一類的用法不是很熟悉,有錯誤或者優化或者需要特別強調的地方希望朋友們幫忙指出來...
C 拷貝建構函式和賦值函式
include using namespace std class string 建構函式 析構函式 賦值函式是每個類最基本的函式。每個類只有乙個析構函式和乙個賦值函式。但有很兩個建構函式,乙個為拷貝建構函式,其他為普通建構函式。對於乙個類,如果不編寫這四個函式,c 編譯器將自動為a產生四個預設函式...