为什么在赋值运算符重载中返回引用

Why a reference is returned in an assignment operator overload?

本文关键字:返回 引用 重载 赋值运算符 为什么      更新时间:2023-10-16

我读到,引用是从重载赋值运算符返回的,以启用运算符链接。但是,如果没有这种回报,运算符链似乎也有效。

有人可以对此有所了解吗?

class A
{
    public:
        int x,y;
        char* str;
        //Default Constructor
        A(){}
        //Constructor
        A(int a, int b, char* s){
            cout<<"initialisingn";
            x = a;
            y = b;
            str = new char[10];
            str = s;
        }
        //Destructor
        ~A(){}
        //Overloaded assignment operator
        const A& operator=(const A& obj)
        {
            cout<<"Invoking Assignment Operatorn";
            x = obj.x;
            y = obj.y;
            str = new char[10];
            str = obj.str;
            //return *this;
        }
};
ostream& operator<<(ostream& os, const A& obj)
{
    os <<"X="<< obj.x<<" Y="<<obj.y<<" Str="<<obj.str<<"n";
    return os;
}
int main()
{
    A c(3,4,"Object C");
    cout<<c;
    A d, e, f;
    d = e = f = c;  //Assignment operator invoked 3 times
    cout<<e;
}

输出:

initialising
X=3 Y=4 Str=Object C
Invoking Assignment Operator
Invoking Assignment Operator
Invoking Assignment Operator
X=3 Y=4 Str=Object C

您遇到了未定义的行为,因为operator =期望返回的类型是const A&,并且您没有返回任何内容。

只是不吉利,它对你有用。(是的,不走运,因为看似有效的未定义行为是最糟糕的(

我在 MSVS 中收到编译错误,ideone.com 遇到运行时错误。

http://ideone.com/xTDb6

此规则源自如下代码:

struct Foo { 
    Foo& copy(const Foo& x) { 
        return (*this = x); 
    } 
};

当时,C++有两点不同:

  1. 编译器生成的运算符 = 默认返回一个右值,并且
  2. 编译器允许非常量引用绑定到临时引用。

上面的代码旨在等效于:

*this = x;
return *this;

但是,事实并非如此 - 由于operator=返回了一个右值,编译器生成了一个临时值来保存赋值的结果,然后由于该函数返回了一个引用,它返回了对该临时值的引用。然后,当然,事情进展得很糟糕,因为你现在有一个悬而未决的引用,指的是一个临时的,它在创建它的完整表达式结束时被销毁了。简而言之,返回对局部引用的类情况 - 除了需要相当多的分析才能意识到本地正在生成,更不用说对它被返回的引用了。

如果您将operator=定义为返回值而不是引用,则必须生成一个临时值,就像编译器在上面的代码中所做的那样。我还没有详细考虑其余部分,以确定当前语言的其他更改是否足以在这种情况下保护你,但我的第一反应是,你距离重建那个古老的错误已经走了一半,所以除非你在这件事上别无选择,否则我会远离。