聊聊C++中複製建構函式和賦值操作符

來源:互聯網
上載者:User

複製建構函式:只有單個形參,而且形參是對本類類型對象的引用(常用const修飾),這樣的建構函式稱為複製建構函式。與預設建構函式一樣,複製建構函式可由編譯器隱式調用。複製建構函式可以用於:

  • 根據另一個同類型的對象顯式或隱式初始化一個對象
  • 複製一個對象,將它作為實參傳給一個函數
  • 從函數返回時複製一個對象
  • 初始化順序容器中的元素
  • 根據元素初始化列表初始化數組元素

賦值操作符:與複製建構函式一樣,如果沒有定義自己的賦值操作符,則編譯器會合成一個。

下面我寫了一個程式對以上描述做出解釋。

#include<iostream>#include<string>#include<vector>using namespace std;class Test{public:Test(){str="Kevin";x=10;cout<<"default constructor"<<endl;}//construction functionTest(const Test& t){str=t.str;x=t.x; cout<<"copy construction was used!"<<endl;}//copy constructor Test& operator=(const Test& t){str=t.str;x=t.x;cout<<"operator="<<endl;return *this;}private:string str;int x;};Test f(Test t){cout<<"f function"<<endl;return t;}main(){cout<<"Test t:"<<endl;Test t;cout<<endl<<"vector<Test> vec1(5):"<<endl;vector<Test> vec1(5);cout<<endl<<"vector<Test> vec2(5,t):"<<endl;vector<Test> vec2(5,t);cout<<endl<<"Test te[5]:"<<endl;Test te[5];cout<<endl<<"Test t2(t):"<<endl;Test t2(t);cout<<endl<<"f(t2):"<<endl;f(t2);cout<<endl<<""<<endl;Test* p1=new Test();*p1=t;Test* p2=&t;Test t3=t;Test t4;t4=t;}

以上程式的輸出結果是:

default constructorvector<Test> vec1(5):default constructorcopy construction was used!copy construction was used!copy construction was used!copy construction was used!copy construction was used!vector<Test> vec2(5,t):copy construction was used!copy construction was used!copy construction was used!copy construction was used!copy construction was used!Test te[5]:default constructordefault constructordefault constructordefault constructordefault constructorTest t2(t):copy construction was used!f(t2):copy construction was used!f functioncopy construction was used!default constructoroperator=copy construction was used!default constructoroperator=

     由上面程式中的第26行可以看出,複製建構函式被用於初始化容器元素的時候,如果沒有之處元素的初始值,則編譯器會首先調用預設的建構函式建立一個臨時制,然後使用複製建構函式將臨時制複製到每一個元素中。當指明了元素的初始值(如29行所示)時,編譯器會直接將其複製到每一個元素。

     由程式中第32行的運行結果可以看出,定義一個類類型的數組時,編譯器會利用類的預設建構函式初始化每一個元素。

由程式中第38行的運行結果可以看出,當類類型被用做形參與傳回值時,各自發生了一次複製。C++ primer中這樣描述:“當函數的形參為非參考型別的時候,將複製實參的值。類似的,以非參考型別做傳回值時,將返回return語句中的值的副本”。按照我的理解就是“當形參和傳回值都不是引用時,進入函數時發生一次複製,離開函數時發生一次複製”。

     程式的第41行至第46行是為了說明複製建構函式與賦值操作符的區別設計的。我們可以看到*p1=t;這一句用到了賦值操作符,t4=t;這一句也用到了賦值操作符,其他各種形式的語句都用的是複製建構函式。從中可以總結出一句話“從無到有是copy,從有到有是賦值”。這句話怎麼理解呢?大家看,*p1=t這一句中的*p是早已經聲明了的,在*p1聲明的時候已經完成了它的初始化。在*p1=t這句中*p是已經初始化過的,所以這裡*p1=t應用的是賦值操作符。同理第46行的中的t4也是一個已經聲明過,完成了初始化的變數,所以在語句t4=t中使用的也是賦值操作符。而在Test t3=t;
 這樣的語句中,t3是剛剛聲明出來的,還沒有初始化,要求編譯器按照t的內容初始化t3。這正好是複製建構函式的作用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.