拷貝賦值操作符
拷貝賦值操作符英文是copy assignment operator。
當你沒有顯示的寫出該函數時,編譯器會爲你聲明一個default copy assignment operator
因此,當你寫下:
class empty {};
就好像寫下了:
class empty{
public:
empty() {};//defualt 構造函數
empty(const empty& rhs)//默認拷貝構造函數
~empty()//析構函數
empty& operator=(const empty& rhs) {};//copy assignment operator
1.以下兩種情況會導致默認的copy assignment operator失效。
class person
{
private:
string & mname;
public:
person(string & name)
:mname(name){}//reference類型必須使用初始化列表來初始化該變量
};
int main(void)
{
person s1(string ("tom"));
person s2(string ("tony"));
//錯誤,包含了引用類型的類無法調用默認拷貝賦值操作符
s1 = s2;
}
因爲reference自身是沒法指向其他地方,所以C++的響應就是拒絕編譯。
如果你打算在一個內涵reference成員的class內支持賦值操作,那麼必須自定義copy assignment operator。
還有const類型的變量也是一樣的。更改const是不合法的。
還有一種情況下,默認的copy assignment operator也是失效的。
class animal
{
private:
//注意該operator爲private
animal& operator=(const animal& hrs);
};
class person :public animal
{
public:
person(){}
//假如我不聲明operator=
//person& operator=(const person& hrs);
};
int main(void)
{
person p1;
person p2;
p2 = p1;//錯誤,因爲無法調用子類的copy assignment operator
}
因爲父類的copy assignment operator需要調用子類的該方法,但是private控制了訪問權限。
解決辦法就是自己寫一個copy assignment operator。
2.有時候想阻止class默認的的copy assignment operator
你可以這樣做:
class uncopyable
{
private:
//只聲明,不實現
uncopyable& operator=(const uncopyable& hrs);
};
假如,不幸在該類的其他函數中使用了copy assignment operator,那麼機智的你一定知道,不實現會導致鏈接的錯誤。
假如你希望把鏈接階段的錯誤提示在編譯的階段就提示,你還可以這樣做:
class uncopyable
{
private:
//只聲明,不實現
uncopyable& operator=(const uncopyable& hrs);
};
class test : private uncopyable
{
};
int main(void)
{
test p1;
test p2;
p1 = p2;//錯誤,無法調用基類的copy assignment operator
}
這樣就會在編譯階段提示錯誤,而不是到了鏈接階段。
1>------ 已啓動全部重新生成: 項目: acm, 配置: Debug Win32 ------
1> main.cpp
1>c:\users\cmm\documents\visual studio 2013\projects\acm\acm\main.cpp(26): error C2248: “uncopyable::operator =”: 無法訪問 private 成員(在“uncopyable”類中聲明)
1> c:\users\cmm\documents\visual studio 2013\projects\acm\acm\main.cpp(22) : 參見“uncopyable::operator =”的聲明
1> c:\users\cmm\documents\visual studio 2013\projects\acm\acm\main.cpp(19) : 參見“uncopyable”的聲明
1> 此診斷出現在編譯器生成的函數“test &test::operator =(const test &)”中
========== 全部重新生成: 成功 0 個,失敗 1 個,跳過 0 個 ==========