《剑指offer》01--赋值运算符函数[C++]

目录

题目描述

解题思路

经典解法

高级解法

知识点


题目描述

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

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

private:
    char* m_pData;
};

解题思路

1. 返回值的类型需声明为该类型的引用,并在函数结束前返回该实例自身的引用(*this)。这样才可以允许连续赋值。

2. 传入的参数类型需声明为常量引用。如果传入参数是实例,从形参到实参就会调用一次复制构造函数,造成无谓的消耗;同时,赋值运算符函数内不会改变传入实例的状态,故应在传入的引用参数上加const。

3. 在分配新内存前,要释放自身已有空间,避免内存泄漏。传入参数的数据大小与当前实例已有空间大小未必一致,故需释放自身已有空间并重新分配内存。

4. 需要判断传入的参数和当前的实例(*this)是不是同一个实例。如果是,则不赋值,直接返回。倘若不判断,在释放自身内存时就会导致严重问题。

5. 需要保证重新分配内存失败时,原有实例不会被修改。一种办法是,先用new分配新内容,成功后再delete已有内容;另一种办法是,先创建一个临时实例,再交换临时实例和原有实例。

经典解法

没有考虑异常安全性。

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;
}

高级解法

针对问题:如果提前释放内存后再申请内存时,内存不足抛出异常,原来的实例将变成空指针,从而很容易导致程序崩溃。

解决办法:先创建一个临时实例,再交换临时实例和原来的实例。此时,倘若内存分配失败,原来的实例不会被修改。临时实例出if作用域便自动析构,就完成了内存释放。

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;
}

知识点

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贫道绝缘子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值