zoukankan      html  css  js  c++  java
  • C++ 赋值运算符函数

    本文为博主原创文章,未经博主允许不得转载 http://www.cnblogs.com/kiplove/p/6783497.html

    C++的重载运算符,由关键字operator和运算符号共同组成,一般而言C++里只要运算符不含"."都可以重载。

    这里主要讲一下赋值运算符的重载。

    一、一个重载赋值运算符的的例子

    class Mystring
    {
    public:
    //    Mystring()=default;
        Mystring(string pData="null")
        {
            m_pData=new string;
            *m_pData=pData;
        }
        Mystring(const Mystring &str)
      {
        
    m_pData=new string;
        *m_pData=*str.m_pData;
      }
    ~Mystring(void){delete m_pData;}
        Mystring& operator=(const Mystring &ptr)
        {
            if(this==&ptr)
                return *this;
            delete m_pData;
            m_pData=NULL;
            m_pData=new string;
            *m_pData=*ptr.m_pData;
            return *this;
        }
        string print(){return *m_pData;}
    private:
        string *m_pData;
    };
    
    int main()
    {
        Mystring a("hello");
        Mystring b,c;
        b=c=a;
    //  (b=c)=a;
        cout<<a.print()<<b.print()<<c.print()<<endl;
        return 0;
    }

    二、分析

    1、返回值类型

    返回类型一般声明为类型的引用,并在函数结尾时返回实例自身的引用(即*this)。这里主要有两个原因:

    a.返回引用可以减少一次拷贝构造和析构函数导致不必要的开销,因为返回值类型不是引用,会创建一个匿名对象,这个匿名对象时个右值,获取return的值。

    b.可以实现连续赋值

     在例子中

      b=c=a;

     返回值不是引用类型也是可以的,其运算顺序

      b=(c=a);

     c得到一个右值,再将右值赋给b,所以逻辑上没有问题的。但是如果是

      (b=c)=a;

     这里将会出错,b=c后b是一个右值,所以b=a时将会出错。

    2、参数

    参数声明为const且是一个引用

    a.const 是因为赋值运算,不希望修改原来类的状态,同时可以接受const与非const的参数

    b.引用则避免了拷贝构造函数

    3、判断是否是传入实例与当前实例是同一个(证同测试),保证自赋值的安全

    如果相同,直接返回可以减少不必要的操作

    同时防止指向的同一资源一起被销毁。

    class Widget{
        ……
        private:
        Bitmap: pb;
    }
    Widget& Widget::operator=(const Widget& rhs)
    {
        delete pb;
        pb=new Bitmap(*rhs.pb);
        return *this;
    }
    //当出现*this与rhs是同一对象时会出现指向对象被删除

    4、赋值前,释放自身的内存

    三、考虑异常安全性

    异常安全函数保证:

    a.不泄露任何资源
    b.不允许数据破坏

    对于第一点一般可以用资源管理类可以实现,采用智能指针,综合两点保证可以用通过copy-and-swap实现异常安全。

     Mystring& operator=(const Mystring &ptr)
     {
            if(this!=&ptr)
            {
                Mystring temp(ptr);
                string ptemp=*temp.m_pData;
                *temp.m_pData=*m_pData;
                *m_pData=ptemp;
            }
            return *this;
     }

     

  • 相关阅读:
    cocos3 单击
    cocos3 帧动画
    cocos3 动作和帧动画
    cocos3 场景切换特效
    cocos3 场景切换
    cocos3 error C2440
    c++ 匿名函数
    【leetcode】生成每种字符都是奇数个的字符串
    【leetcode】山羊拉丁文
    【leetcode】字符串的最大公因子
  • 原文地址:https://www.cnblogs.com/kiplove/p/6783497.html
Copyright © 2011-2022 走看看