我發現一些同事在編寫乙個類時,知道什麼時候需要實現拷貝建構函式和賦值操作,但不知道什麼時候拷貝建構函式被呼叫,什麼時候賦值操作被呼叫,甚至把二者混為一談。
要弄明白這個問題,最簡單的做法莫過於寫個測試程式試一下。不過那樣做也未必是好辦法,實驗的結果往往導致以偏概全的結論。不如好好想一下,弄清楚其中的原理,再去寫程式去驗證也不遲。
拷貝建構函式,顧名思義,等於拷貝 + 構造。它肩負著建立新物件的任務,同時還要負責把另外乙個物件拷貝過來。比如下面的情況就呼叫拷貝建構函式:
cstring str = strother;
賦值操作則只含有拷貝的意思,也就是說物件必須已經存在。比如下面的情況會呼叫賦值操作。
str = strother;
不過有的物件是隱式的,由編譯器產生的**建立,比如函式以傳值的方式傳遞乙個物件時。由於看不見相關**,所以不太容易明白。不過我們稍微思考一下,就會想到,既然是根據乙個存在的物件拷貝生成新的物件,自然是呼叫拷貝建構函式了。
兩者實現時有什麼差別呢?我想有人會說,沒有差別。呵,如果沒有差別,那麼只要實現其中乙個就行了,何必要兩者都實現呢?不繞圈子了,它們的差別是:
拷貝建構函式對同乙個物件來說只會呼叫一次,而且是在物件構造時呼叫。此時物件本身還沒有構造,無需要去釋放自己的一些資源。而賦值操作可能會呼叫多次,你在拷貝之前要釋放自己的一些資源,否則會造成資源洩露。
明白了這些道理之後,我們不寫保護個測試程式來驗證一下我們的想法:
#include
<
stdio
.h>
#include
#include
<
string
.h>
class
cstring ;
cstring
::cstring()
cstring
::cstring
(const
char
* pszbuffer)
cstring
::~cstring()
cstring
::cstring
(const
cstring
& other)
printf
("cstring::cstring(const cstring& other)/n");
m_pszbuffer
= other
.m_pszbuffer
!= null
? strdup
(other
.m_pszbuffer
) :
null;
}
const
cstring
& cstring
::operator
=(const
cstring
& other)
if(
m_pszbuffer
!= null)
m_pszbuffer
= other
.m_pszbuffer
!= null
? strdup
(other
.m_pszbuffer
) :
null;
return
*this;
}
void
test
(cstring
str)
int
main
(int
argc
, char
* argv)
C 物件的拷貝與賦值操作
我發現一些同事在用c 編寫乙個類時,知道什麼時候需要實現拷貝建構函式和賦值操作,但不知道什麼時候拷貝建構函式被呼叫,什麼時候賦值操作被呼叫,甚至把二者混為一談。要弄明白這個問題,最簡單的做法莫過於寫個測試程式試一下。不過那樣做也未必是好辦法,實驗的結果往往導致以偏概全的結論。不如好好想一下,弄清楚其...
C 物件的拷貝與賦值操作
c 物件的拷貝與賦值操作 我發現一些同事在編寫乙個類時,知道什麼時候需要實現拷貝建構函式和賦值操作,但不知道什麼時候拷貝建構函式被呼叫,什麼時候賦值操作被呼叫,甚至把二者混為一談。要弄明白這個問題,最簡單的做法莫過於寫個測試程式試一下。不過那樣做也未必是好辦法,實驗的結果往往導致以偏概全的結論。不如...
C 中淺拷貝 深拷貝 物件的複製 物件的賦值
一 概念字面理解 1 淺拷貝 發生物件複製時,只是對對像張資料成員進行簡單的賦值。涉及到動態分配問題,如果按淺拷貝進行複製,不做特殊處理,複製完成後,兩個物件中涉及動態分配空間的變數,不管他們各自的空間,及空間中的內容都是完全一樣的,當對這兩個物件進行析構時,會發生同一片空間被釋放兩次,因而會出現錯...