Google C++編程規范 – 第三十二條 -《拷貝構造函數》
【規范】
僅在確認需要的時候,才定義拷貝構造函數和賦值運算符;否則,請使用DISALLOW_COPY_AND_ASSIGN關閉此功能。
【定義】
我們通過拷貝構造函數和賦值運算符來實現對一個類對象的拷貝。在一些情況下,編譯器會隱式的調用拷貝構造函數,比如在以值傳遞方式傳遞對象時。
【支持者的聲音】
拷貝構造函數,使得拷貝一個類對象變得很容易。STL容器更是規定其內容都要是可拷貝和可賦值的。拷貝構造方式要比CopyFrom方式更加高效,這是因為拷貝構造方式將構造和拷貝兩者結合起來了。而且在一些上下文中編譯器會省略掉它們,並且它們會更容易的避免堆分配。
【反對者的聲音】
隱式的類對象拷貝會引入很多bug和性能方面的問題,還會因為很難追蹤一個類對象的行為而導致代碼的可讀性的降低。
【結論】
只有很少的類需要進行拷貝。而大多數的類既不需要拷貝構造函數,也不需要賦值運算符。在很多情況下,一個指針或一個引用其實已經足夠,而且還會有更好的性能表現。比如,你可以通過傳入指針、引用來代替傳入一個值,你還可以在STL容器中保存對象的指針,而非對象本身。
如果你的類就是需要可拷貝,那么最好提供一個拷貝方法,比如CopyFrom()或Clone(),而非一個拷貝構造函數,這樣可以有效的避免隱式調用。如果拷貝方法還不足以滿足你的需求(比如性能方面的原因,或者你的類就是需要在容器中保存對象本身),那么請同時提供拷貝構造函數和賦值運算符。
如果你的類不需要拷貝構造函數或賦值運算符,那么請顯式的禁用它們。禁用的方法是在類的private區域中增加一個拷貝構造函數和賦值運算符的啞聲明,但是不要提供相應的定義。
DISALLOW_COPY_AND_ASSIGN本身是一個宏,其定義如下:
// 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&)
然后,我們可以在Foo類中這樣使用:
class Foo {
public:
Foo(int f);
~Foo();
private:
DISALLOW_COPY_AND_ASSIGN(Foo);
};
