void doSomething(const Base& rb, // rb and *pd might actually be Derived* pd); // the same object 假如你遵循 Item 13 和14 的建议,你应该总是使用对象来治理资源,而且你应该确保那些资源治理对象(resource-managing objects)被拷贝时行为良好。假如是这种情况,你的赋值运算符在你没有考虑自拷贝的时候可能也是自赋值安全(self-assignment-safe)的。但是,假如你试图自己治理资源,无论如何(假如你写一个资源治理类(resource-managing class),你当然不得不做),你可能会落入在你使用完一个资源之前就已意外地将它释放的陷阱。例如,假设你创建了一个类,它持有一个指向动态分配 bitmap 的指针:
class Bitmap { ... };
class Widget { ... PRivate: Bitmap *pb; // ptr to a heap-allocated object }; 下面是一个 Operator= 的实现,表面上看它是合理的,但假如出现自赋值则是不安全的。(它也不是异常安全(exception-safe)的,但我们要过一会儿才会涉及到它。)
Widget& Widget::operator=(const Widget& rhs) // unsafe impl. of operator= { delete pb; // stop using current bitmap pb = new Bitmap(*rhs.pb); // start using a copy of rhs’s bitmap
Widget& Widget::operator=(const Widget& rhs) { Bitmap *pOrig = pb; // remember original pb pb = new Bitmap(*rhs.pb); // make pb point to a copy of *pb delete pOrig; // delete the original pb