剑指offer-1.赋值元素运算符函数

0 题目

为了一个类添加一个赋值运算符函数

class Str 
{
public:
    Str(char *p=nullptr);
    Str(const Str& str);
    ~str();
private:
    char* m_data;
}

  

1 分析

赋值运算符,也就是重载=号运算符。重载赋值运算符需要注意:

  1. 返回自身引用,因此可以实现连=操作
  2. 传入参数为引用,减少开销
  3. 如果类内对象,由在堆上分配内存。或者说是类的析构函数会释放某些数据成员,那么该数据成员就需要深度拷贝
  4. 传入自身的时候,需要判断是否需要赋值
  5. 在赋值发生错误的时候,能够回滚到原来的状态。

2 方案

Str &Str::operator=(/*const*/ Str &str)
{
    if (this != str)
    {
        Str tmp(str); // 使用已有的拷贝拷贝构造函数,拷贝构造函数默认已经是深拷贝
        swap(tmp);
        // 离开作用域的时候,tmp带着this原来的m_data被 Str的析构函数析构了
    }
    return this;
}

void Str::swap(Str &str)
{
    char *tmp = str.m_data;
    str.m_data = m_data;
    m_data = tmp;
    // 如果有其他需要交换的,那么在后面添加
}

// 另一种实现,不在传入应用,直接在传值截断进行 拷贝,
// 性能靠编译器来优化
Str &Str::operator=(Str str)
{
    Str tmp(str); // 使用已有的拷贝拷贝构造函数,拷贝构造函数默认已经是深拷贝
    swap(tmp);
    // 离开作用域的时候,tmp带着this原来的m_data被 Str的析构函数析构了
    return this;
}

 

原文地址:https://www.cnblogs.com/perfy576/p/8554918.html