“自我赋值”发生在对象被赋值给本身时:安全
class Widget { ... }; Widget w; ... w = w; //赋值给本身
operator=,不只不具有“自我赋值安全性”,也不具有“异常安全性”。函数
让operator= 具有“异常安全性”每每自动得到“自我赋值安全性”的回报。所以愈来愈多的人对“自我赋值”的处理态度是不去管它,而把焦点放在实现“异常安全性”上。this
确保代码不但“异常安全”并且“自我赋值安全”的一个替代方案是,使用所谓的copy and swap技术。此技术和“异常安全性”有密切关系,它是一个常见而够好的operator=撰写办法,其实现方式为:spa
class Widget { public:
... void swap(Widget& rhs); //交换*this和任rhs的数据 ... }; Widget& Widget::operator=(const Widget& rhs) { Widget temp(rhs); //为rhs数据制做一份复件(副本) swap(temp); //将*this数据和上述复件的数据交换 return *this; }
另一种实现方式为:对象
Widget& Widget::operator=(Widget rhs) //rhs是被传对象的一份复件(副本),注意此处是值传递 pass by value { swap(rhs); //将*this数据和复件的数据交换 return *this; }
上述实现方式由于:一、某类的copy assignment操做符可能被声明为“以by value方式接受实参”;二、以by value方式传递东西会形成一份复件/副本blog
此方式牺牲了清晰性,然而将拷贝动做从函数本体移至“函数参数构造阶段”却可令编译器有时生产更高效的代码get
请牢记:编译器
一、确保当前对象自我赋值时operator= 有良好行为。其中技术包括比较“来源对象”和“目标对象”的地址、精心周到的语句顺心、以及copy-and-swap。编译
二、肯定任何函数若是操做一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确。class