zoukankan      html  css  js  c++  java
  • 3.异常安全的赋值运算符重载

    一、题目

      如下为类型CMyString,请为该类型添加赋值运算符函数。

     1 class CMyString
     2 {
     3 public:
     4     CMyString(char* pData)
     5     {
     6         m_pData = new char[strlen(pData) + 1];
     7         strcpy(m_pData, pData);
     8     }
     9 
    10     CMyString(): m_pData(NULL) {}
    11 
    12 
    13     CMyString(const CMyString& str);
    14     
    15     ~CMyString()
    16     {
    17         delete []m_pData;
    18     }
    19 
    20     CMyString& operator =(const CMyString& str);
    21 
    22     void Print() const
    23     {
    24         printf("%s
    ", m_pData);
    25     }
    26 
    27 
    28 private:
    29     char* m_pData;
    30 };

    二、经典解法

      经典解法代码实现如下:

     1 CMyString& CMyString::operator =(const CMyString &str)
     2 {
     3     // 自身赋值
     4     if (this == &str)
     5         return *this;
     6 
     7 
     8     m_pData = new char[strlen(str.m_pData) + 1]; // 加一,为存放字符串的结束符''
     9     strcpy(m_pData, str.m_pData);
    10 
    11     return *this;
    12 }

      这是一个经典的解法,为了防止自身赋值,先判断复制对象,是否是自身,如果是,则什么都不做。这个方法可以应对常规的情况。但是,其没有考虑异常安全。在这里的

    new char[],可能会由于内存不足导致其抛出异常。

    三、考虑异常安全的解法

      实现代码如下:

     1 CMyString& CMyString::operator =(const CMyString &str)
     2 {
     3     if (this != &str)
     4     {
     5         CMyString strTemp(str);
     6 
     7         char* pTemp = strTemp.m_pData;
     8         strTemp.m_pData = m_pData;
     9         m_pData = pTemp;
    10     }
    11 
    12     return *this;
    13 }

      在该赋值函数中,如果判断不是自身赋值,那么先用拷贝构造函数以str构造一个临时对象strTemp,此时对于char的内存分配转移到临时对象的拷贝构造函数中,如果抛出异常,那么对于该实例本身来说,没有任何改变,不影响该实例本身的使用。如果临时对象没有出异常,那么将实例自身的m_pData和strTemp.m_pData交换,由于strTemp是临时对象,在作用域结束时,自动调用析构函数,释放内存,而此时的strTemp的m_pData已经指向了原实例的m_pData的内存。这样就能自动释放内存了。同时也是异常安全的。

      

  • 相关阅读:
    MS SQLSERVER 第三天
    MS SQLSERVER 第二天
    今天开始我的 MSSQLSERVER 之旅
    从今天开始就正式我的博客之旅
    mac 本地搭建mybatisGenerator代码生成环境
    idea中git远程版本回退
    Junit调试解决本地多线程异步调用
    Lambda表达式总结
    JDK8函数式编程之Stream API
    MySql分页查询慢的解决方案
  • 原文地址:https://www.cnblogs.com/wangjzh/p/4355514.html
Copyright © 2011-2022 走看看