effective c++ 11: Handle assignment to self in operator =
比如有这样一个class:
class A {}; class B { ... private: A* a; };
在写class B的赋值函数的时候,假如写成下面这样:
B& B::operator=(const B& rhs) { delete a; a = new A(*rhs.a); return *this; }
假如是自我赋值,那上面这个代码显然就不对了,*this和rhs是一个对象,所以如果都delete a 了下面还怎么new A(*rhs.a)呢。
可以通过identity test检查是否是自我赋值:
if(this==&rhs) return *this
在上面那个自我赋值会产生问题的代码里,还有一处安全隐患(不具备“异常安全性”),就是即使不是自我赋值,假如在new的时候出现了异常,那么A的指针a还是指向了不安全的区域。
可以通过下面的方法解决这个问题:
B& B::operator=(const B& rhs) { A* pOrig = a; a = new A(*rhs.a);//a指向原来a的一个副本 delete pOrig; return *this; }
这样即使在new的时候出现了异常,a还是指向原来的a。
还有个方案是copy and swap
class B { .. void swap(B& rhs); .. }; B& B::operator=(const B& rhs) { B tmp(rhs); //rhs的副本 swap(tmp); return *this; }