zoukankan      html  css  js  c++  java
  • 在operator =中要处理“自我赋值”

    防止自我赋值很有必要

    Widget w;
    w = w;
    a[i] = a[j]; //a[i]和a[j]实际上指向同一个元素
    *pi = *pj; //pi和pj实际上指向同一个元素

    自我赋值的危害

    Widget
    {
    private:
        Test *p;
    };
    Widget &Widget::operator=(const Widget &w)
    {
      delete p;
      p = new int (*w.p);
      return *this;
    }

    如果是自我赋值,会把自己的空间释放掉,即当执行delete p后,w.p已经指向一个被释放的内存空间(此时*w.p的内容未知);当执行 p = new int(*w.p);即让p重新指向一个存储了(*w.p)的内存空间,该内存空间内容又是未知的。当再次引用时,会出现未定义的行为。

    改良版本

    Widget &Widget::operator=(const Widget &w)
    {
      if (this == &w)
      {
          return *this;
      }
      delete p;
      p = new Test(*w.p);
      return *this;
    };

    这个类虽然能避免自我赋值的问题,但是,如果new Test时抛出异常,那么Widget最终会持有一个指针指向一块被删除的内存区域,这样的指针是有害的。

    改成这样

    Widget &Widget::operator=(const Widget &rhs)
    {
      Test *porg = p;
      p = new Test(*rhs.p);
      delete porg;
      return *this;
    }

    此时new Test发生异常,那么p可以保持原状。(异常发生的时候,不会给p赋值)

    delete prog;保证了p原来指向的内存空间也会被顺利释放。

  • 相关阅读:
    c#多线程控制
    SQL解析XML文件
    c#时间差高精度检查
    SQL Server数据库级别触发器
    c#做对比软件
    项目管理开源软件
    信息量、信息熵、交叉熵、相对熵
    GAN评价指标之mode score
    Fréchet Inception Distance(FID)
    图片的多样性之模式崩溃
  • 原文地址:https://www.cnblogs.com/codingmengmeng/p/9065280.html
Copyright © 2011-2022 走看看