zoukankan      html  css  js  c++  java
  • 面试题1:赋值运算符函数

    题目:如下为类型CMyString的声明,请为该类型添加赋值运算符函数。

    class CMyString
    {
      public:
        CMyString(char* pData = NULL);
        CMyString(const CMyString&str);
        ~CMyString(void);
      private:
        char* m_pData;
    };

    考点:

    • 是否把返回值的类型声明为该类型的引用,并在函数结束前返回该实例自身的引用(*this)。只有这样才允许连续赋值。
    • 是否把传入的参数的类型声明为常量引用。避免改变实例状态以及参数拷贝造成的无谓消耗。
    • 是否释放实例自身已有的内存。避免内存泄露。
    • 是否判断传入的参数和当前的实例是否为同一个实例。

    初级程序员解法:

    CMyString& CMyString::operator = (const CMyString&str)
    {
      if (this == &str)
        return *this;
      delete []m_pData;
      m_pData = NULL;
          m_pData = new char[strlen(str.mpData)+1];
      strcpy(m_pData, str.m_pData);
      return *this;
    }

    上述代码存在的问题:

    先释放内存,再分配新的内存,一旦新的内存分配失败,则m_pData将是一个空指针,CMyString的实例不再保持有效状态,违背了异常安全性原则。

    解决方法1:先判断内存是否分配成功,再释放原有内存。

    解决方法2:先创建一个临时实例,再交换临时实例和原来的实例。

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

    分析:我们的目的是要释放原来内存,开辟新的内存,同时遵守异常安全性原则。在上述代码中,先创建一个临时变量strTemp,在此过程中会通过拷贝构造函数开辟新的内存,然后交换strTemp与m_pData的指针。由于strTemp是临时变量,作用域在if内,因此当程序运行到if的外面时就会调用该变量的析构函数释放strTemp.m_pData所指向的内存。同时,如果由于内存不足抛出异常,也不会对原来实例的状态产生影响,也就保证了异常安全性原则。

  • 相关阅读:
    docker私有仓库搭建及使用
    服务器ip迁移纪要
    Windows 下QT程序发布
    Prometheus监控软件部署方法
    android的listview控件,加了行内按钮事件导致行点击失效的问题
    惊奇!Android studio内部在调用Eclipse
    关于Android Stuido2.3和Eclipse4.4
    XCODE9.1的一些新问题
    osx12.6设置全屏
    IEEE754浮点数与字节数互转工具
  • 原文地址:https://www.cnblogs.com/happygirl-zjj/p/4609825.html
Copyright © 2011-2022 走看看