Effect C++ 读书笔记: 构造函数/析构函数/赋值运算符 2

来源:互联网 发布:javascript post提交 编辑:程序博客网 时间:2024/05/13 00:19
/* 本工程名CDAProjct2表示 C++中的构造/析构和赋值 */

#include <iostream>

using namespace std;

/************************************************/
/* 条款6: 令operater=返回一个reference to *this    */
/************************************************/

/* 目的:实现"连锁赋值",不仅适用于标准赋值形式,也适用于赋值相关的运算 */

/************************************************/
/*         条款7:在operator=中处理"自我赋值"        */
/************************************************/


/* 陷阱:在停止使用资源之前就释放它 */
class Bitmap
{
public:
    Bitmap(const char* m):msg(m) {}
    void printmsg() { cout<<"Message: "<<msg<<endl; }
private:
    std::string msg;
};

class Widget
{
public:
    Widget& operator=(const Widget& rhs); //operator= 操作符
private:
    Bitmap *pb;
};

/*
Widget& Widget::operator=(const Widget& rhs)
{
    if(this == &rhs) return *this;

    delete pb;
    pb=new Bitmap(*rhs.pb); //使用Bitmap的copying函数
    return *this;
}
*/

/*
上面赋值操作符代码的问题是:
operator=函数内的*this(赋值的目的端)和rhs有可能是同一个对象
若果真如此,那么delete就不只是销毁当前对象的bitmap,它也销毁了
rhs的bitmap。函数末尾,Widget发现自己持有一个指针指向一个已经
被删除的对象
*/

/* 解决方法:认同测试 */
/* if(this == &rhs) return *this; */
/*
但上面的代码仍然无法获得“异常安全性”,即如果new Bitmap导致异常
那么Widget将会持有一个指针指向一块被删除的Bitmap
*/

/*
然而,让operator=具有"异常安全性"往往自动获得"自我赋值安全"的回报
*/
Widget& Widget::operator=(const Widget& rhs)
{
    Bitmap* pOrig=pb;
    pb=new Bitmap(*rhs.pb); //使用Bitmap的copying函数
    delete pOrig;

    return *this;
}

/***************************************************/
/*          条款8:复制对象是不要忘记其每一个部分         */
/***************************************************/
/* 特别是遇到继承的情况:不要忘记复制base class的部分
*/

int main()
{
    /*
    Bitmap* pb1=new Bitmap("This is bitmap1");
    Bitmap* pb2=pb1;
    pb1=new Bitmap("This is bitmap2");
    pb2->printmsg();
    pb1->printmsg();
    */
    Widget wg1;
    wg1=wg1;
    return 0;
}