1. 程式人生 > >劍指offer— (1) 賦值運算子函式

劍指offer— (1) 賦值運算子函式

題目描述:    如下為型別CMyString的宣告,請為該型別新增賦值運算子函式。

實現如下:  是我的解法,適合C++初級程式設計師

//
// Created by yanpan on 2018/9/30.
//
#if 1
#include <iostream>
using namespace std;

class CMyString
{
public:
    CMyString()
    {
        m_pdata = new char[1];
    }
    CMyString(char *name)
    {
        m_pdata = new char[strlen(name)+1];
        strcpy(m_pdata,name);
    }
    CMyString(const CMyString& str);
    CMyString& operator = (const CMyString& str)  //需要連續賦值所以要返回引用
    {
        cout<<"CMyString& operator =(const CMyString& str)"<<endl;
        if (this == &str)    //判斷是不是自賦值
            return *this;
        delete[]m_pdata;
        m_pdata = nullptr;
        m_pdata = new char[strlen(str.m_pdata)+1]; //分配空間
        strcpy(m_pdata,str.m_pdata);
        return *this;
    }
    ~CMyString()
    {
        delete[]m_pdata;
        m_pdata = NULL;
    }
    void show()
    {
        if(this == NULL)
            return;
        cout<<m_pdata<<endl;
    }
private:
    char* m_pdata;
};

int main()
{
    CMyString str1;
    CMyString str2("world");
    CMyString str3;
    str3 = str1 = str2;  //要連續賦值   連續賦值是呼叫兩次賦值函式
    str1.show();
    str3.show();
    cout<<"hello"<<endl;
    return 0;
}
#endif

考慮異常的安全解法:   先建立一個臨時例項,接著把strTemp.m_pdata 和 例項自身的 m_pdata 進行交換。因為 strTemp是一個區域性變數,程式執行到if 外面時就出了該變數的作用域,就會自動呼叫strTemp的解構函式,把strTemp.m_pData所指向的記憶體釋放掉,由於strTemp.m_pdata所指向的記憶體是例項之前m_pdata的記憶體,這就相當於自動呼叫解構函式釋放了例項的記憶體。

CMyString(const CMyString& str)
    {
        cout<<"CMyString(const CMyString& str)"<<endl;
        m_pdata = new char[strlen(str.m_pdata)+1];
        strcpy(m_pdata,str.m_pdata);
    }
//防止申請記憶體時沒有申請成功,對原有例項的狀態還沒有修改 保證異常安全性
    CMyString& operator = (const CMyString& str)  //需要連續賦值所以要返回引用
    {
        cout<<"CMyString& operator =(const CMyString& str)"<<endl;
        if (this != &str)
        {
            CMyString strTemp(str);
            char *pTemp = strTemp.m_pdata;
            strTemp.m_pdata = m_pdata;
            m_pdata = pTemp;
        }
        return *this;
    }