zoukankan      html  css  js  c++  java
  • Effective C++ 条款11,12 在operator= 中处理“自我赋值” || 复制对象时不要忘记每一个成分

    1、潜在的自我赋值

        a[i] = a[j];

        *px = *py;

    当两个对象来自同一个继承体系时,他们甚至不需要声明为相同类型就可能造成别名。

    现在担心的问题是:假如指向同一个对象,当其中一个对象被删,另一个也被删,这会造成不想要的结果。

    该怎么办?

    比如:

      widget& widget:: operator+ (const widget& rhs)

    {

       delete pd;

       pd = new bitmap(*rhs.pb);

       return *this; //这里假如*this与rhs是同一个对象。则不好处理。

    }

    解决方案:

        1、证同测试

            判断是不是同一个对象,如果是同一个对象,则是自我赋值,不用做任何事。

            if(this = &rhs)  return *this;

        2、记住原先的pb,就是在开辟一个空间存放其原来的地址。我们只需记住在复制pb所指东西前别删除pb;

            Bitmap * pOrig = pb;                  //记住原先的pb

            pb = new Bitmap(*rhs.pb);         //令pb指向*pb的一个副本

            delete pOrig;                           //删除原先的pb

            return *this;

        3、直接制作一个副本(引用传递)

           widget temp(rhs);   //为rhs数据制作一个副本

           swap(temp);

        4、值传递

            swap(rhs);

    记住:

          1、确保党对象自我赋值时,有良好的行为。其中的技术包括以上四种。

          2、确保如果任何函数操作一个以上的对象,而其中多个对象是同一个对象时,其行为一定正确。

         还记得条款5中提到编译器在必要时会为我们提供拷贝构造函数和拷贝赋值函数,它们也许工作的不错,但有时候我们需要自己编写自己的拷贝构造函数和拷贝赋值函数。如果这样,我们应确保对“每一个”成员进行拷贝(复制)。
    如果你在类中添加一个成员变量,你必须同时修改相应的copying函数(所有的构造函数,拷贝构造函数以及拷贝赋值操作符)。
    在派生类的构造函数,拷贝构造函数和拷贝赋值操作符中应当显示调用基类相对应的函数,否则编译器可能又“自作聪明了”。
         当你编写一个copying函数,请确保:  

        (1)复制所有local成员变量;

        (2)调用所有基类内的适当copying函数。

    但是,我们不该令拷贝赋值操作符调用拷贝构造函数,也不该令拷贝构造函数调用拷贝赋值操作符。想想,一个是拷贝(建立对象),一个是赋值(对象已经存在)。


    请记住:

    • 1、Copying函数应该确保复制“对象内的所有成员变量”及“所有基类成员”;
    • 2、不要尝试以某个copying函数实现另一个copying函数。应该将共同机能放进第三个函数中,并由两个copying函数共同调用。 

  • 相关阅读:
    dll得到主窗體的handle
    将应用程序11M内存占用,降至500K
    是否想为你的Windows加上一双眼睛,察看使用者在机器上所做的各种操作(例如建立、删除文件;改变文件或目录名字)呢?
    TreeView 之间节点拖动 /移动
    Delphi与C之间的类型对应表
    以ADO数据集相连的DBGrid按单一字段排序通用过程
    为Delphi程序添加事件和事件处理器
    DataSetToTreeView
    一个系统空闲时间函数
    调用chm
  • 原文地址:https://www.cnblogs.com/zhuxuekui/p/3916205.html
Copyright © 2011-2022 走看看