繁体   English   中英

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

[英]Why a reference is returned in an assignment operator overload?

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

有人可以阐明这一点吗?

class A
{
    public:
        int x,y;
        char* str;

        //Default Constructor
        A(){}

        //Constructor
        A(int a, int b, char* s){
            cout<<"initialising\n";
            x = a;
            y = b;
            str = new char[10];
            str = s;
        }

        //Destructor
        ~A(){}

        //Overloaded assignment operator
        const A& operator=(const A& obj)
        {
            cout<<"Invoking Assignment Operator\n";
            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. 默认情况下,由编译器生成的operator =返回一个右值,并且
  2. 编译器允许非常量引用绑定到临时对象。

上面的代码旨在等同于:

*this = x;
return *this;

但是,这不是-因为operator=返回了一个右值,编译器生成了一个临时变量来保存赋值结果,然后由于该函数返回了引用,因此它返回了对该临时变量的引用。 然后,当然,事情匆匆忙忙,因为您现在悬而未决地引用了一个临时对象,该临时对象在创建它的完整表达式的末尾被销毁了。 简而言之,这是一个返回对本地的引用的类情况-除了需要花大量的分析才能意识到本地正在生成时,更不用说对它的引用了。

如果定义operator=返回值而不是引用,则必须生成一个临时值,就像编译器在上面的代码中所做的一样。 我没有仔细考虑其余的内容,以弄清楚在这种情况下当前语言的其他更改是否足以保护您,但是我的直接反应是,您大约要重新构造那个古老的bug,因此,除非您在此问题上别无选择,否则我会远离的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM