C 物件的拷貝與賦值操作

2021-04-07 13:25:51 字數 1793 閱讀 1138

我發現一些同事在編寫乙個類時,知道什麼時候需要實現拷貝建構函式和賦值操作,但不知道什麼時候拷貝建構函式被呼叫,什麼時候賦值操作被呼叫,甚至把二者混為一談。

要弄明白這個問題,最簡單的做法莫過於寫個測試程式試一下。不過那樣做也未必是好辦法,實驗的結果往往導致以偏概全的結論。不如好好想一下,弄清楚其中的原理,再去寫程式去驗證也不遲。

拷貝建構函式,顧名思義,等於拷貝 + 構造。它肩負著建立新物件的任務,同時還要負責把另外乙個物件拷貝過來。比如下面的情況就呼叫拷貝建構函式:

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 淺拷貝 發生物件複製時,只是對對像張資料成員進行簡單的賦值。涉及到動態分配問題,如果按淺拷貝進行複製,不做特殊處理,複製完成後,兩個物件中涉及動態分配空間的變數,不管他們各自的空間,及空間中的內容都是完全一樣的,當對這兩個物件進行析構時,會發生同一片空間被釋放兩次,因而會出現錯...