西西軟件下載最安全的下載網(wǎng)站、值得信賴的軟件下載站!

首頁編程開發(fā)其它知識(shí) → Effective C++禁用編譯器自動(dòng)生成的函數(shù)

Effective C++禁用編譯器自動(dòng)生成的函數(shù)

相關(guān)軟件相關(guān)文章發(fā)表評(píng)論 來源:西西整理時(shí)間:2013/1/11 8:49:03字體大小:A-A+

作者:xd_xiaoxin點(diǎn)擊:6次評(píng)論:0次標(biāo)簽: EffectiveC

  • 類型:電子教程大。16.1M語言:中文 評(píng)分:4.5
  • 標(biāo)簽:
立即下載

如果想讓你的類定義出來的對(duì)象是獨(dú)一無二的,即對(duì)象無法被復(fù)制,或者使用賦值操作符賦給另外一個(gè)對(duì)象,那么最好的方法就是禁用拷貝構(gòu)造函數(shù)和賦值操作符。下面介紹幾種禁用的方法。(方法來自Effective C++,如果想禁用類的其他函數(shù),方法類似)

1. 定義為private且不實(shí)現(xiàn)它

我們知道,拷貝構(gòu)造函數(shù)和賦值操作符重載函數(shù),即使不定義,編譯器也會(huì)生成一個(gè)默認(rèn)的函數(shù)。但是如果定義了,class還是會(huì)支持這兩個(gè)函數(shù)。那么應(yīng)該怎么去禁用它們呢?

在C++中,如果不想讓對(duì)象調(diào)用某個(gè)方法,那么可以將這個(gè)方法聲明為private,因此,我們可以將拷貝構(gòu)造函數(shù)和賦值操作符重載函數(shù)聲明為private,就可以阻止別人調(diào)用它了。但是,private函數(shù)還是可以在類的成員函數(shù)和friend函數(shù)中調(diào)用。這里還有一個(gè)技巧,就是將函數(shù)定義為private而且不實(shí)現(xiàn)它。

class SpecialClass {
    ...
private:
    SpecialClass(const SpecialClass&);
    SpecialClass& operator=(const SpecialClass&);    
};

將SpecialClass這樣定義,并且不實(shí)現(xiàn)這兩個(gè)函數(shù),那么如果有人試圖拷貝這個(gè)類的對(duì)象,編譯器就會(huì)報(bào)錯(cuò):

SpecialClass sc1;
SpecialClass sc2(sc1);        //error, 編譯出錯(cuò)
SpecialClass sc3;
sc3 = sc1;                    //error, 編譯出錯(cuò)

而且即使在成員函數(shù)或者friend函數(shù)中調(diào)用了它,鏈接時(shí)也會(huì)出錯(cuò)。

2. 繼承Uncopyable類

第一種方法可以解決禁用拷貝構(gòu)造函數(shù)的問題,但是還有一點(diǎn)不完美的是,如果用戶不小心在成員函數(shù)或者friend函數(shù)中調(diào)用了它,那么這個(gè)錯(cuò)誤只有到鏈接階段才能被發(fā)現(xiàn)。所以就有了繼承一個(gè)Uncopyable類的方法:

class Uncopyable {
protected: 
    Uncopyable() {}
    ~Uncopyable() {}
private:
    Uncopyable(const Uncopyable&);
    Uncopyable& operator=(const Uncopyable&);
};

此時(shí),只需要繼承Uncopyable類就可以防止其對(duì)象被拷貝了。其原理是:SpecialClass繼承了Uncopyable函數(shù),它的對(duì)象如果調(diào)用了拷貝構(gòu)造函數(shù),或者使用了賦值操作符,那么編譯時(shí),就會(huì)去調(diào)用基類的對(duì)應(yīng)函數(shù),但是基類里的這兩個(gè)函數(shù)是private的,所以編譯會(huì)失敗。

另外,boost也提供了一個(gè)Uncopyable函數(shù),那個(gè)class名字為noncopyable,因此我們也可以這樣做:

#include <boost/utility.hpp>

class SpecialClass : boost::noncopyable {
    ...
};

3. C++0x中的新方法

在C++0x中,新添加了兩個(gè)關(guān)鍵字:default和delete,可以用于控制某個(gè)類使用默認(rèn)函數(shù)(default)或者禁用某個(gè)函數(shù)(delete)。其中,使用default關(guān)鍵字可以將某個(gè)函數(shù)定義為默認(rèn)函數(shù)。如:

class SpecialClass {
    ...
public:
    SpecialClass(const SpecialClass&) = default;
    SpecialClass& operator=(const SpecialClass&) = default;    
};

可能這樣寫有點(diǎn)多余,但是它可以直觀表示“我使用的默認(rèn)的函數(shù)”。而且,如果有人想顯式定義默認(rèn)函數(shù),但是自己寫的代碼又可能有錯(cuò)誤,就可以使用這個(gè)關(guān)鍵字,方便且不出錯(cuò)。

delete關(guān)鍵字可以禁用掉類的方法,正如我們上面前兩節(jié)所做的事情,就可以用這一個(gè)關(guān)鍵字完成:

class SpecialClass {
    ...
public:
    SpecialClass(const SpecialClass&) = delete;        //禁用拷貝構(gòu)造函數(shù)
    SpecialClass& operator=(const SpecialClass&) = delete;    
};

default關(guān)鍵字可以用于一切含有默認(rèn)方法的函數(shù)。delete關(guān)鍵字可以用于類的所有方法,例如可以禁用掉函數(shù)的某些類型的參數(shù):

class SpecialClass {
    ...
public:
    void fn(long);
    void fn(int) = delete;
};

SpecialClass sc;
long l;
sc.fn(l);        //ok, 調(diào)用void fn(long);
int i;
sc.fn(i);        //error, 調(diào)用void fn(int);

上面的代碼會(huì)將void fn(int)類型的函數(shù)禁用掉,而如果不禁用的話,sc.fn(i)會(huì)進(jìn)行隱式轉(zhuǎn)換調(diào)用void fn(long)函數(shù)。

    相關(guān)評(píng)論

    閱讀本文后您有什么感想? 已有人給出評(píng)價(jià)!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評(píng)論

    最新評(píng)論

    發(fā)表評(píng)論 查看所有評(píng)論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評(píng)論需要經(jīng)過審核才能顯示)
    推薦文章

    沒有數(shù)據(jù)