为什么C++中拷贝赋值运算符必须返回一个引用

通过一段代码说明这个问题

#include 

class A{
public:
    A() : m_age(0){ std::cout << "construvtor invoked." << std::endl; }
    A(const int age):m_age(age){
        std::cout << "int constructor invoked" << std::endl;
    }
    A(const A & rhs):m_age(rhs.m_age){
        std::cout << "copy constructor invoked." << std::endl;
    };
    A operator=(const A& rhs);
    ~A(){
        std::cout << "destructor invoked." << std::endl;
    }
private:
    int m_age = 0;
};
A A::operator=(const A &rhs) {
    std::cout << "copy assignment operator invoked." << std::endl;
    m_age = rhs.m_age;
    return *this;
}
class B{
public:
    B() : m_age(0){ std::cout << "construvtor invoked." << std::endl; }
    B(const int age):m_age(age){
        std::cout << "int constructor invoked" << std::endl;
    }
    B(const B & rhs):m_age(rhs.m_age){
        std::cout << "copy constructor invoked." << std::endl;
    };
    B& operator=(const B& rhs);
    ~B(){
        std::cout << "destructor invoked." << std::endl;
    }
private:
    int m_age = 0;
};
B& B::operator=(const B &rhs) {
    std::cout << "copy assignment operator invoked." << std::endl;
    m_age = rhs.m_age;
    return *this;
}
int main(void)
{
    std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA" << std::endl;
    {
        A a1 = 1;
        A a2 = 2;
        A a3 = 3;
        {
            a1 = a2 = a3;
        }
        std::cout << "hello world" << std::endl;
    }

    std::cout << "BBBBBBBBBBBBBBBBBBBBBBBBBBBBB" << std::endl;
    {
        B b1 = 1;
        B b2 = 2;
        B b3 = 3;
        {
            b1 = b2 = b3;
        }
        std::cout << "hello world" << std::endl;
    }
    return 0;
}

输出如下:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
int constructor invoked
int constructor invoked
int constructor invoked
copy assignment operator invoked.
copy constructor invoked.
copy assignment operator invoked.
copy constructor invoked.
destructor invoked.
destructor invoked.
hello world
destructor invoked.
destructor invoked.
destructor invoked.
BBBBBBBBBBBBBBBBBBBBBBBBBBBBB
int constructor invoked
int constructor invoked
int constructor invoked
copy assignment operator invoked.
copy assignment operator invoked.
hello world
destructor invoked.
destructor invoked.
destructor invoked.

Process finished with exit code 0

通过对比,发现:
如果拷贝赋值运算符重载直接返回值,也可以进行链式赋值,但是增加了很多徒劳无益的操作。额外调用了两次拷贝构造函数,两次析构函数,但是并没有因此而得到什么收益,因此不够高效。

原因在于,每一次调用=运算符,都会生成一个具有表达式作用域的临时对象,这个临时对象的生成需要调用拷贝构造函数,到达作用域的终点时又需要调用析构函数来释放内存空间。

反观class B,只执行了必要的操作,没有任何额外的函数调用,因此这种风格大家比较推崇。

贴一个SO的帖子:

https://stackoverflow.com/questions/3105798/why-must-the-copy-assignment-operator-return-a-reference-const-reference#:~:text=If%20you%20return%20a%20reference,assignment%20operator%20is%20called!!

你可能感兴趣的:(C++,c++,特殊成员函数,类)