【剑指offer】面试题1:赋值运算符函数

题目要求为下面一个类实现一个赋值运算符的函数:

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

我们要实现任意的一个类的赋值运算符函数,都要注意一些方面:

  • 返回值类型是类引用,返回*this
  • 参数类型是常量引用
  • 如果有动态内存,是否发生内存泄露
  • 如果传入参数为调用者自身,直接返回

书上的解法给的确实很完备,而且后来用了一种巧妙的方法让程序自动释放内存。但我觉得重点是他提到的异常安全性的处理,这里的话如果我们在new的时候内存不够,而我们又已经delete掉原来的内存,就会导致调用者的内存被无故释放了;所以书上采用新建临时变量,然后再让*this的m_pData指针和临时变量的m_pDatam做交换,就算如果新建临时变量的时候内存不够,也可以保证调用者调用失败也没有被改变。

但是我想了一下,异常安全性的思想是很宝贵,但是实现起来其实可以用try catch这样也很直观:

CMyString & CMyString::operator = (const CMyString& str) {
    if (this == &str) {
        return *this;
    }
    try{
        delete [] this->m_pData;
        this->m_pData = new char [strlen(str.m_pData) + 1];
        strcpy(this->m_pData, str.m_pData);
    } catch(std::exception& e) {
        std::cout << e.what() << std::endl;
        std::cout << "申请内存错误,赋值失败,返回原对象" << std::endl;
    }
    return *this;
}

这里提到赋值运算符的话,就要顺便说一下拷贝构造函数;

CMyString s2;
CMyString s1 = s2; //这一行其实调用的是拷贝构造函数

区别就在于,拷贝构造函数的调用,之前是没有对象的,所以如果有动态内存,拷贝构造函数肯定不会先去delete;
而赋值运算符是讲一个对象赋给另外一个对象,之前是有对象的,这么一来就有了对之前对象的处理。

我把所有函数的实现和一些注意事项放在这里啦~
https://github.com/preke/AimToOffer/blob/master/01.c%2B%2B

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值