<span style="font-size:14px;">int x, y, z; x=y=z=15;</span>
#include<iostream>
using namespace std;
class Widget
{
public:
Widget()
{
cout<<"Default Ctor"<<endl;
}
Widget(const Widget& rhs)
{
cout<<"Copy Ctor"<<endl;
}
Widget& operator=(const Widget& rhs)
{
cout<<"operator="<<endl;
return *this;
}
};
int main()
{
Widget a,b,c;
a=b=c;
return 0;
}这样输出为:class Widget
{
public:
Widget& operator=(const Widget& rhs)
{
delete p;
p=new int(ths.p);
return *this;
}
int *p;
};如果上面代码自我赋值,在使用指针p之前已经将其释放掉了。class Widget
{
public:
Widget& operator=(const Widget& rhs)
{
if(this==&rhs)//证同测试
return *this;
delete p;
p=new int(rhs.p);
return *this;
}
int *p;
};这个版本的operator=可以解决自我赋值的问题。但是还有个问题:异常安全。如果delete p成功,而p=new int(rhs.)失败会发生什么?class Widget
{
public:
Widget& operator=(const Widget& rhs)
{
int tmp=p;//记录原先内存
p=new int(rhs.p);
delete tmp;//释放原先内存
return *this;
}
int *p;
};在实现异常安全的同时,其实也获取了自我赋值的安全。如果p=new int(ths.p)发生异常,后面的delete tmp就不会执行。class Widget
{
public:
void swap(const Widget& rhs);//交换rhs和this
Widget& operator=(const Widget& rhs)
{
Widget tmp(rhs);//赋值一份数据
swap(tmp)//交换
return *this;//临时变量会自动销毁
}
int *p;
};如果赋值操作符参数是值传递,那么就不需要新建临时变量,直接使用函数参数即可。class Widget
{
public:
void swap(const Widget& rhs);//交换rhs和this
Widget& operator=(const Widget rhs)
{
swap(rhs)
return *this;
}
int *p;
};这个做法代码可读性比较差,但是将“copying动作”从函数体内移到“函数参数构造阶段”,编译器有时会生成效率更高的代码(by moving the copying operation from the body of the function to construction of the parameter, it‘s fact that compiler can sometimes generate more efficient code.class Cutsomer
{
public:
Cutsomer()
{
name="nobody";
}
Cutsomer(const Cutsomer& rhs)
:name(rhs.name)
{
cout<<"Customer Copy Ctor"<<endl;
}
Cutsomer& operator=(const Cutsomer& rhs)
{
cout<<"assign operator"<<endl;
name=rhs.name;
return *this;
}
private:
string name;
};这样的copying函数没有问题,但是如果再给类添加变量,例如添加一个电话号码class Cutsomer
{
……
private:
string name;
string telphone;
};这时copying函数不做更改,即便是在最高警告级别,编译器也不会报错,但是我们的确少拷贝了内容。class PriorityCustomer:public Cutsomer
{
public:
PriorityCustomer()
{
cout<<"PriorityCustomer Ctor"<<endl;
}
PriorityCustomer(const PriorityCustomer& rhs)
:priority(rhs.priority)
{
cout<<"PriorityCustomer Copy Ctor"<<endl;
}
PriorityCustomer& operator=(const PriorityCustomer& rhs)
{
cout<<"PriorityCustomer assign operator"<<endl;
priority=rhs.priority;
return *this;
}
private:
int priority;
};在PriorityCustomer的copying函数中,只是复制了PriorityCustomer部分的内容,基类内容被忽略了。那么其基类内容部分怎么初始化的呢?PriorityCustomer(const PriorityCustomer& rhs)
:Cutsomer(rhs),priority(rhs.priority)
{
cout<<"PriorityCustomer Copy Ctor"<<endl;
}
PriorityCustomer& operator=(const PriorityCustomer& rhs)
{
cout<<"PriorityCustomer assign operator"<<endl;
Cutsomer::operator=(rhs);
priority=rhs.priority;
return *this;
}《Effective C++》构造/析构/赋值 函数:条款10-条款12
原文地址:http://blog.csdn.net/kangroger/article/details/42433437