【C++】C++問(wèn)題——顯式構(gòu)造函數(shù)、常量引用返回值、深淺拷貝

explicit構(gòu)造函數(shù)

所有的單參數(shù)的構(gòu)造函數(shù)都必須是explicit的,以避免后臺(tái)的類(lèi)型轉(zhuǎn)換。否則,一些寬松的規(guī)則將允許在沒(méi)有顯示類(lèi)型轉(zhuǎn)換操作的情況下進(jìn)行類(lèi)型轉(zhuǎn)換。

A a;
a = 37;

上面的代碼構(gòu)造了一個(gè)A對(duì)象a,并進(jìn)行賦值。該賦值語(yǔ)句不能正常工作,因?yàn)樵谫x值符號(hào)右側(cè)并不是另一個(gè)A對(duì)象。
然而,C++擁有寬松的規(guī)則,通常,單參數(shù)構(gòu)造函數(shù)定義了一個(gè)隱式類(lèi)型轉(zhuǎn)換(implicit type conversion),該轉(zhuǎn)換創(chuàng)建了一個(gè)臨時(shí)對(duì)象,從而使賦值(或函數(shù)參數(shù))變成兼容的。
在本例中,編譯器試圖將a = 37;轉(zhuǎn)換成A temp(37); a = temp;
臨時(shí)對(duì)象的構(gòu)造也可以通過(guò)使用單參數(shù)構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)。使用explicit意味著單參數(shù)構(gòu)造函數(shù)不能用來(lái)創(chuàng)建隱式臨時(shí)對(duì)象。

參數(shù)傳遞小結(jié)

  1. 按值調(diào)用適用于不被函數(shù)更改的小對(duì)象
  2. 按常量引用調(diào)用適用于不被函數(shù)更改的大對(duì)象
  3. 引址調(diào)用適用于所有可以被函數(shù)更改的對(duì)象

按常量引用返回

如果返回的對(duì)象是類(lèi)類(lèi)型,使用按常量引用返回可以節(jié)省復(fù)制的開(kāi)銷(xiāo)。這里的const是指返回的對(duì)象自身不能修改。
如果你想從常量成員函數(shù)中通過(guò)引用返回this對(duì)象的一個(gè)成員,你應(yīng)該使用常量引用來(lái)返回它,即const X& 。也就是說(shuō)你想通過(guò)引用返回的東西如果從邏輯上來(lái)講是this對(duì)象的一部分(與它是否在物理上嵌入在this對(duì)象中無(wú)關(guān)),那么常量方法需要通過(guò)常量引用或者通過(guò)值來(lái)返回,而不能通過(guò)非常量引用返回。

下面給出一個(gè)例子:

const string & findMax(const vector<string> & arr)
{
    int maxIndex = 0;
    for(int i=1;i<arr.size();i++)
        if(arr[maxIndex] < arr[i])
            maxIndex = i;
    return arr[maxIndex];
}

這里,表達(dá)式arr[maxIndex]索引的vector是在findMax外部的,并且存在時(shí)間長(zhǎng)于調(diào)用返回的時(shí)間,這在函數(shù)返回時(shí),返回的表達(dá)式依然有效,所以可以用常量引用返回。

operator[]

下面的程序我們來(lái)討論一下返回引用和常量引用。
這個(gè)程序的意思是,如果有一個(gè)matrix m,那么m[i]就應(yīng)該返回一個(gè)對(duì)應(yīng)的matrix m的行i的向量。
operator[]應(yīng)該返回vector<Object>的實(shí)體。返回引用的話(huà)可以減少對(duì)象復(fù)制的消耗。

#include <vector>
using namespace std;
template <typename Object>
class matrix
{
    public:
    ...
    const vector<Object> & operator[](int row) const
    {
        return array[row];
    }
    vector<Object> & operator[](int row)
    {
        return array[row];
    }
    
    ...
    private:
    vector< vector<Object> > array;
}

如果operator[]返回常量引用,那么返回的引用不能成為左值;如果僅僅只是為了訪問(wèn)矩陣的值,返回的不是常量向量又不能算是優(yōu)秀的設(shè)計(jì)。
所以,實(shí)際需要的是operator[]返回一個(gè)常量引用和一個(gè)普通引用兩個(gè)版本。但返回值不算是函數(shù)簽名的一部分,而const是簽名的一部分,所以將返回常量引用的訪問(wèn)函數(shù)設(shè)定為const成員函數(shù)。于是,我們可以使訪問(wèn)函數(shù)版本的operator[]返回常量引用,而修改函數(shù)版本的則返回簡(jiǎn)單引用。

數(shù)據(jù)成員是指針的類(lèi)

假設(shè)類(lèi)僅包含一個(gè)指針數(shù)據(jù)類(lèi)型,并且這個(gè)指針指向一個(gè)動(dòng)態(tài)分配地址的對(duì)象。默認(rèn)的析構(gòu)函數(shù)不對(duì)指針進(jìn)行任何操作。而且,復(fù)制構(gòu)造函數(shù)和operator=都不復(fù)制指針?biāo)赶虻膶?duì)象,而是簡(jiǎn)單地復(fù)制指針的值。這樣一來(lái),就得到了兩個(gè)類(lèi)實(shí)例,它們包含的指針都指向了同一個(gè)對(duì)象。這被稱(chēng)為淺復(fù)制(shallow copy,指針被復(fù)制而不是指針?biāo)傅膶?duì)象被復(fù)制)。
一般,我們期望得到的是對(duì)整個(gè)對(duì)象進(jìn)行克隆的深復(fù)制(deep copy)。于是,當(dāng)一個(gè)類(lèi)含有的數(shù)據(jù)成員為指針并且深復(fù)制很重要的時(shí)候,一般的做法就是必須實(shí)現(xiàn)析構(gòu)函數(shù)、operator=和復(fù)制構(gòu)造函數(shù)。

參考資料

常量函數(shù)、常量引用參數(shù)、常量引用返回值C++

轉(zhuǎn)載請(qǐng)注明作者Jason Ding及其出處
Github博客主頁(yè)(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡(jiǎn)書(shū)主頁(yè)(http://www.itdecent.cn/users/2bd9b48f6ea8/latest_articles)
百度搜索jasonding1354進(jìn)入我的博客主頁(yè)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容