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

class CMyString
{
public:
    CMyString(char* pData = nullptr);
    CMyString(const CMyString& str);
    ~CMyString(void);

private:
    char* m_pData;
};

A:对于一个赋值运算符函数的注意点。1. 是否把返回值的类型声明为该类型的引用,且在函数结束前返回实例自身的引用(*this) 2. 是否把传入的参数的类型声明为常量引用 3. 是否释放实例自身已有的内存 4.判断传入的参数和当前的实例(*this)是不是同一个实例

初级程序员解法:

CMyString& CMyString::operator=(const CMyString& str)
{
    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;
}

问题来了,如果此时内存不足,new char抛出异常,则m_pData将是一个空指针,这样非常容易导致程序崩溃,违背了异常安全性原则。可以先创建一个临时实例,在交换临时实例和原来的实例。

高级程序员解法:

CMyString& CMyString::operator=(const CMyString& str)
{
    if (this != &str)
    {
        CMyString strTemp(str);
        char* pTemp = strTemp.m_pData;
        strTemp.m_pData = m_pData;
        m_pData = pTemp;
    }

    return *this;
}