<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