zoukankan      html  css  js  c++  java
  • effective c++ (四)

    条款10:令operator=返回一个reference to *this

    为了实现“连锁赋值”,赋值操作符必须返回一个reference指向操作符的左侧实参,这是你为classes实现赋值操作符时应该遵循的协议。

    class Widget{
    public:
          ...
          Widget& operator+=(const Widget& rhs)   //同样适用于-=, *=
          {
                  ...
                  return *this;
          }
    
          Widget& operator=(const Widget& rhs)   //同样适用于-=, *=
          {
                  ...
                  return *this;
          }
    
          Widget& operator=(int rhs)   //此函数也是和,即使此一操作符参数类型不符合协定
          {
                  ...
                  return *this;
          }
    };

    注意,这只是一个协议,并无强制性。如不遵循它,代码一样可以通过编译。然而这份协议被所有内置类型和标准程序库提供的类型工作遵守(string vector  complex tr1::shared_ptr)

    请记住:

    • 令赋值操作符(assignment)操作符返回一个reference to *this

    条款11:在operator=中处理“自我赋值”

    1、一般而言,如果某段代码操作pointers或references而它们被用来“指向多个相同类型”,就需要考虑这些对象是否为同一个。实际上,两个对象只要来自同一个继承体系,甚至不需要声明为相同类型就可能造成“别名”(应为base class的指针或引用可以指向一个derived)。如:

    a[i] = a[j] //若i与j具有相同的值,这便是自我赋值;

    *px = *py//如果px与py恰巧指向同一个对象,则时自我赋值

    void doSomething(const Base& rb, Derived* pd);//若rb与rp可能指向同一个对象

     2、如果遵循条款13和14的忠告,你会运用对象来管理资源,而且你可以确定所谓“资源管理对象”在copy发生时有正确的举措。在这种情况下你的赋值操作符或许是“自我赋值安全的”(self-assignment-safe),不需要额外操心

    3、如下代码,在自我赋值时会会抛出异常

    class Bitmap { ... };
    class Widget 
    {
          ...
    private:
       Bitmap* pb;  
    };
    
    Widget& Widget::Operator=(const Widget& rhs)
    {
        delete pb;
        pb = new Bitmap(*rhs.pb);
       return *this;       
    }

    这里若是自我复制问题是,operator=函数内的*this和rhs有可能是同一对象;若是如此delete就不只是销毁当前对象的bitmap,也销毁了rhs的bitmap

    Widget& Widget::operator=(const Widget& rhs)
    {
         if(this == &rhs) return *this;
         delete pb;
         pb = new Bitmap(*rhs.pb);
         return *this; 
    }

    如此在赋值前进行一个“认同测试(identify test)”达到自我赋值的检验目的

    但是此段代码不具备“异常安全性”,在new Bitmap导致异常(不论是因为分配时内存不足或因为Bitmap的copy构造函数抛出异常),Widget最终会持有一个指针指向一块被删除的Bitmap。

  • 相关阅读:
    一些tips
    微信小程序之后端处理
    微信小程序之前端代码篇
    微信小程序踩坑之前端问题处理篇
    Vue组件封装之一键复制文本到剪贴板
    读别人的代码之bug的发现
    解析webpack插件html-webpack-plugin
    数组去重方法整理
    如何理解EventLoop--浏览器篇
    axios和vue-axios的关系
  • 原文地址:https://www.cnblogs.com/penghuster/p/6262404.html
Copyright © 2011-2022 走看看