close

原文:
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Copy_Constructors

C++中的class是value type by default(C#和Java中的class是reference type by default),在撰寫C++程式時,難免需要class instances之間的拷貝,Copy ctor和assignment operator就是用於這種場合。當你從一個現有的class instance來創建另一個class instance時,Copy ctor就會被呼叫。當你把一個現有的class instance用賦值給另一個class instance時,assignment operator就會被呼叫。copy ctor和assignment operator也常用於STL container之中。若沒有為class宣告copy ctor或assignment operator時,compiler會為你隱式生成

其實只有少數的class有被拷貝的需求,而compiler隱式生成的copy ctor和assignment operator常是bug的根源,也會造成performance上的問題(和call-by-reference比起來),而且copy ctor和assignment operator會降低程式的可讀性,因為它們不像一般的function一樣,必須顯式的去呼叫它;所以你往往難以trace到底哪些地方呼叫了copy ctor或assignment operator。所以Google C++ Style Guide規定只有當你有拷貝需求時才去實作copy ctor和assignment operator,若沒有這樣的需求;則必須使用goole自定義的macro DISALLOW_COPY_AND_ASSIGN來防止compiler隱式產生copy ctor和assignment operator,而DISALLOW_COPY_AND_ASSIGN不過就是copy ctor和assignment operator的宣告,你必須把它放在private access level裡面。

// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
    TypeName(const TypeName&);             \
    void operator=(const TypeName&)

把該macro用於class CFoo:

class CFoo {
public:
    CFoo(int f);
    ~CFoo();

private:
    DISALLOW_COPY_AND_ASSIGN(CFoo);
};

使用DISALLOW_COPY_AND_ASSIGN時切記不要提供copy ctor和assignment operator的定義,如此一來拷貝CFoo時就會出現link error。

也因為class instances之間的拷貝有這些問題,所以Google C++ Style Guide也建議,如果你有performance上的考量,可以使用call-by-reference來取代call-by-value,或是將class的pointer存於STL container而非class的instance。你也可以自己定義拷貝函數(CopyFrom()或Clone()),並將class instance的拷貝實作於此,來避免可讀性上的問題(Java的object有提供拷貝函數clone())。當然如果你的class有用於STL container的需求,還是要自定義copy ctor和assignment operator。

arrow
arrow
    文章標籤
    C++
    全站熱搜

    coherence 發表在 痞客邦 留言(0) 人氣()