C++之拷贝构造函数&赋值运算符

2021-07-22  本文已影响0人  上官宏竹

赋值运算符

注意几点:

  1. 参数定义为MyStr& operator =(const MyStr& str),const可以接收左值引用和右值引用(为啥可以参考:C++11之右值引用&移动语义
  2. 判断入参是否是本身
  3. 返回参数为引用。原因除了避免拷贝、避免临时对象出现后在栈中需要多增加的一次拷贝外,另外是可以实现连续赋值,即类似a=b=c这样。如果不是返回引用而是返回值类型,那么,执行a=b时,调用赋值运算符重载函数,在函数返回时,由于返回的是值类型,所以要对return后边的“东西”进行一次拷贝,得到一个未命名的副本(有些资料上称之为“匿名对象”),然后将这个副本返回,而这个副本是右值,所以,执行a=b后,得到的是一个右值,即右值=c,再执行=c就会出错。

调用时机

什么情况下调用赋值运算符,什么情况下调用拷贝构造函数?
简单来说=号右边是一个前面已经定义好的变量时,是调用的赋值运算符。如下所示c1 = c;,是c1调用了operator =()函数。

Array c(5);
Array c1(50);
Array d = c;    // 拷贝构造函数
c1 = c;         // 赋值运算符

移动赋值运算符

主要是为了接收右值的赋值操作。定义为:Array& operator=(Array &&rhs)

拷贝构造函数、赋值运算符及其移动语义

class Array {
public:
    // 构造函数
    Array(int size) : m_size(size) {
        m_data = new int[m_size];
        cout << "struct funtion, m_data: " << m_data <<" size: "<< m_size << endl;
    }

    // 拷贝构造函数
    Array(const Array& temp_array) {
        m_size = temp_array.m_size;
        m_data = new int[m_size];
        for (int i = 0; i < m_size; i++) {
            m_data[i] = temp_array.m_data[i];
        }

        cout << "copy struct funtion, m_data: " << m_data << " size: " << m_size << endl;
    }

    // 移动构造函数
    Array(Array && rhs) {
        m_size = rhs.m_size;
        m_data = rhs.m_data;
        rhs.m_data = nullptr;

        cout << "move struct funtion, m_data: " << m_data << " size: " << m_size << endl;
    }

    // 赋值运算符
    Array& operator=(const Array& temp_array) {
        if (this != &temp_array) {  // 避免自赋值
            delete[] m_data;

            m_size = temp_array.m_size;
            m_data = new int[m_size];
            for (int i = 0; i < m_size; i++) {
                m_data[i] = temp_array.m_data[i];
            }

            cout << "=operator funtion, m_data: " << m_data << " size: " << m_size << endl;
        }

        return *this;
    }
    
    // 移动赋值运算符
    Array& operator=(Array &&rhs) {
        if (this != &rhs) { // 避免自赋值
            m_size = rhs.m_size;
            m_data = rhs.m_data;
            rhs.m_data = nullptr;

            cout << "move =operator funtion, m_data: " << m_data << " size: " << m_size << endl;
        }

        return *this;
    }

    ~Array() {
        delete[] m_data;
    }

public:
    int * m_data;
    int m_size;
};

int main()
{
    cout << "========赋值运算符&拷贝构造函数=========" << endl;
    Array c(5);     // 构造函数
    Array c1(50);   // 构造函数
    Array d = c;    // 拷贝构造函数
    c1 = c;         // 赋值运算符
    
    cout << "========移动语义=========" << endl;
    Array e1 = std::move(c);    // 移动构造函数
    Array e2(3);                // 构造函数
    e2 = std::move(c1);         // 移动赋值运算符

    return 0;
}

运行结果:


参考:一文说尽C++赋值运算符重载函数(operator=)

上一篇下一篇

猜你喜欢

热点阅读