C++:構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)與運(yùn)算符重載

釋義:

  • 構(gòu)造函數(shù):初始化對(duì)象的數(shù)據(jù)成員的一種函數(shù)。
  • 拷貝構(gòu)造函數(shù):以本類的對(duì)象引用作為參數(shù)的構(gòu)造函數(shù),目的是拷貝對(duì)象。
  • 運(yùn)算符重載:重新定義運(yùn)算符行為,用以適應(yīng)不同的數(shù)據(jù)類型,本質(zhì)為函數(shù)重載。

示例:

下面這個(gè)簡(jiǎn)單的例子分別描述了帶參構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)和賦值運(yùn)算符重載。

class A{
    public:
    int a;
    //constructor
    A(int a_tmp){
        a = a_tmp;
    }
    //copy constructor
    A(const A& A_tmp){
        a = A_tmp.a;
    }
    //member assignment operator
    A& operator=(const A& A_tmp){
        a = A_tmp.a;
        return *this;
    }
}
//non-member operator overload
A operator+(const A& A1,const A& A2){
    A A_tmp;
    A_tmp.a = A1.a+A2.a;
    return A_tmp;
}

思考:

  1. 拷貝構(gòu)造函數(shù)的理解:
    • 拷貝構(gòu)造函數(shù)的重點(diǎn)是構(gòu)造函數(shù),因此copy ctor只有在變量的定義處才會(huì)被調(diào)用,本質(zhì)還是一種構(gòu)造函數(shù)。
    • 如果沒有顯式定義拷貝構(gòu)造函數(shù),那么編譯器會(huì)為類自動(dòng)定義一個(gè)按位拷貝的默認(rèn)拷貝構(gòu)造函數(shù)。需要注意默認(rèn)拷貝構(gòu)造函數(shù)只會(huì)對(duì)成員變量做簡(jiǎn)單的賦值運(yùn)算來完成拷貝動(dòng)作,因此對(duì)于指針型變量會(huì)出現(xiàn)淺拷貝的問題。(淺拷貝:src和dst是同一塊內(nèi)存區(qū)域;深拷貝:src和dst不在同一塊內(nèi)存區(qū)域。)
    • 禁止拷貝構(gòu)造函數(shù):將拷貝構(gòu)造函數(shù)聲明為private可以禁止使用拷貝構(gòu)造函數(shù)。一般而言,將構(gòu)造函數(shù)聲明為private都可以禁止調(diào)用。這就是單例模式的實(shí)現(xiàn)方式。
    • 對(duì)于B:A這種派生類,B的默認(rèn)構(gòu)造函數(shù)會(huì)調(diào)用A的默認(rèn)構(gòu)造函數(shù),如果重載了B的構(gòu)造函數(shù),若需要指定A的構(gòu)造函數(shù),則需要顯式調(diào)用,否則會(huì)調(diào)用A的默認(rèn)構(gòu)造函數(shù)。例如如果要調(diào)用A的拷貝構(gòu)造函數(shù),則需要這樣寫:
B(const B& B_tmp):A(B_tmp){
    ...
}
  1. 運(yùn)算符重載的理解:
    • 為什么運(yùn)算符重載的返回值大多都是引用之一:原理上來說返回值可以為任何類型,比如可以為基本類型、類或者void,但是基于兩個(gè)方面考慮,一方面是為了便于連續(xù)運(yùn)算,比如a=b=c,b=c運(yùn)算完為了能繼續(xù)給a賦值,=運(yùn)算符會(huì)返回左值b,這里的左值可以是對(duì)象也可以是對(duì)象的引用。但是,另一方面,如果返回了對(duì)象,那么在函數(shù)返回后會(huì)調(diào)用構(gòu)造函數(shù)創(chuàng)建臨時(shí)變量用于存儲(chǔ)返回值進(jìn)行下一次a=運(yùn)算,相比返回對(duì)象引用開銷更大,因此返回對(duì)象的引用是性能較好而且更通用的做法。
    • 為什么運(yùn)算符重載的返回值大多都是引用之二:實(shí)際上返回引用意味著有能力返回左值,C++ 中函數(shù)可以返回左值的功能對(duì)實(shí)現(xiàn)一些重載的操作符是非常重要的,比如方括號(hào)運(yùn)算符[],返回引用意味著能進(jìn)行類似myVector[2] = 3.5這樣的操作。
    • 注意成員運(yùn)算符重載和非成員運(yùn)算符重載的差異,他們的參數(shù)個(gè)數(shù)是不一樣的,見上述代碼。
    • 對(duì)于B:A這種派生類,運(yùn)算符重載需要顯式調(diào)用A的對(duì)應(yīng)運(yùn)算符,否則A類內(nèi)部不會(huì)發(fā)生任何改變。例如:
B& operator+(const B& B_tmp){
    A:operator+(B_tmp);
    ...
    return *this;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • C++語言的一個(gè)很有意思的特性就是除了支持函數(shù)重載外還支持運(yùn)算符重載,原因就是在C++看來運(yùn)算符也算是一種函數(shù)。比...
    歐陽(yáng)大哥2013閱讀 2,720評(píng)論 0 8
  • 3. 類設(shè)計(jì)者工具 3.1 拷貝控制 五種函數(shù)拷貝構(gòu)造函數(shù)拷貝賦值運(yùn)算符移動(dòng)構(gòu)造函數(shù)移動(dòng)賦值運(yùn)算符析構(gòu)函數(shù)拷貝和移...
    王偵閱讀 1,861評(píng)論 0 1
  • 基本上我們進(jìn)行運(yùn)算符重載時(shí)有兩種形式,類內(nèi)的運(yùn)算符重載和頂層函數(shù)位置的運(yùn)算符重載。 操作符重載指的是將C++提供的...
    飛揚(yáng)code閱讀 1,691評(píng)論 0 4
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,533評(píng)論 1 51
  • 我已被綁架,只希望你以後不要成為我,而我必不會(huì)變成她。
    海陵燕飛閱讀 125評(píng)論 0 0