拷貝構造函式呼叫的時機

2021-04-27 16:06:45 字數 950 閱讀 6629

拷貝函式何時會被呼叫呢?最明顯的就是用乙個類物件初始化另外乙個物件的時候

比如x a=x(); 這句語義上就是先建立x()臨時物件,再呼叫x的拷貝建構函式「初始化」a,

這只是語義上的,編譯器完全可能優化掉臨時物件 。注意區分初始化和賦值(呼叫assignment operator)

第二種情況是函式按值傳引數的時候,包括指標在內都是對原有的值的拷貝 。這種情況容易理解。

第三種情況是乙個物件以值傳遞的方式從函式返回。

為什麼要這個時候會呼叫拷貝建構函式呢?因為在函式內, 所有的變數都是在函式的棧上的,包括那個引數,等函式完了以後都會銷毀

所以就必須給它拷貝乙份傳回。 以下面**為例,我們看看編譯器是如何將物件以值傳遞方式從函式返回的。

1.首先宣告乙個額外的引數,型別上類物件的引用,用來存放返回結果,本例中為&_retvalue。

2.對這個引數利用返回值進行拷貝初始化。過程類似於引數傳遞,也是要定義乙個臨時物件sum,用來儲存返回值,然後在函式內部呼叫拷貝建構函式將_retvalue初始化。

有時編譯器為了減少構造析構的次數,會把事先建立好的物件的引用傳進來,然後對其修改,這就是所謂的nrv(named return value (nrv) optimization,具名返回值優化)。仍以上面**為例,上述**可能轉換為

nrv優化的本質是優化掉拷貝建構函式,去掉它不是生成它。當然了,因為為了優化掉它,前提就是它存在,這個也就是nrv優化需要有拷貝建構函式存在的原因。 nrv優化會帶來***,不用它的確造成很大的效能損失,知道這個情況就可以了。 

第四種情況是非空順序容器型別的定義,例如vectorsvec(5);string預設建構函式建立乙個臨時物件,然後通過string拷貝建構函式將該臨時物件被一次拷貝到vector的五個元素中。

第五種情況是將乙個類物件插入到容器型別中,例如svec.push_back(string("sfsd"));

呼叫拷貝建構函式的時機

在c 中,下面三種物件需要呼叫拷貝建構函式 有時也稱 複製建構函式 1 乙個物件作為函式引數,以值傳遞的方式傳入 函式體 2 乙個物件作為函式返回值,以值傳遞的方式從函式返回 3 乙個物件用於給另外乙個物件進行初始化 常稱為賦值初始化 includeusing namespace std class...

拷貝建構函式被呼叫的時機

拷貝建構函式被呼叫的時機 1.當用類的乙個物件去初始化該類的另乙個物件 或引用 時系統自動呼叫拷貝建構函式實現拷貝賦值。2.若函式的形參為類物件,呼叫函式時,實參賦值給形參,系統自動呼叫拷貝建構函式。3.當函式的返回值是類物件時,系統自動呼叫拷貝建構函式。下面給出乙個例子 cpp view plai...

C 拷貝構造函式呼叫時機

class a 傳入乙個字串代表變數的名字 a string n name n a 拷貝建構函式a const a a 過載 運算子 a operator const a a friend ostream operator ostream os,const a a private string na...