拷贝赋值操作符
拷贝赋值操作符英文是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 个 ==========