Effective C++ 條款05:瞭解C++默默編寫並呼叫哪些函式
阿新 • • 發佈:2021-06-23
一些說明
我們定義一個空類
class Empty {}
等價於
class Empyt {
Empty() {}
Empty(const Empty& rhs) {...}
~Empty() {}
Empty& operator=(const Empty& rhs) {...}
}
-
預設建構函式
-
預設拷貝建構函式
-
預設賦值運算子過載
-
預設解構函式
這些函式會在被呼叫的時候建立。
預設拷貝建構函式只是單純的將每個非靜態成員變數拷貝到另一個物件中。
例子
template <typename T> class NamedObject{ public: NamedObject(string& name, const T& value) :nameValue(name), objectValue(value){} private: string& nameValue; const T objectValue; };
我們定義了一個NamedObject類,用來給物件命個名。這個類有兩個成員變數:string引用型別的nameValue和一個const的T物件。注意這兩個成員變數的型別,這很重要。
然後我們自己定義了一個建構函式,所以編譯器不會為我們定義預設的建構函式。
下面我們使用這個類。首先定義了兩個NamedObject物件,然後試圖賦值給另一個。
int main() { string newDog("Persephone"); string oldDog("Satch"); NamedObject<int> p(newDog, 2); NamedObject<int> s(oldDog, 36); p = s; // wrong }
由於我們沒有自己寫賦值運算子,所以編譯器會生成預設賦值運算子過載。但上文談到,預設的賦值運算子過載是簡單的將物件的每個成員函式賦值給另一個。但這裡的nameValue成員變數是個string引用。引用可以理解成一個常量指標,它一定與它指向的物件是繫結的。
但是這裡如果我們執行賦值操作,本意是想修改p的名字。但這裡的p的名字是個newDog物件的引用。如果要賦值的話就會修改newDog的內容。預設的賦值運算子過載能隨便修改別的物件的內容嗎?
編譯器的處理是拒絕執行賦值。因為如果你想通過賦值運算子過載修改別的物件的內容,那麼請自己寫。