在进行类对象赋值的链接时获取垃圾值,使用赋值运算符重载,它按值返回类对象

时间:2017-02-07 13:00:18

标签: c++

在赋值运算符重载中,如果我通过引用返回对象,如下所示

One& operator=( const One&  obj).

然后程序运行正常。

但是,如果我按价值返回,如下所示

One operator=( const One&  obj)

然后o1获得垃圾值。任何人都可以解释为什么按值返回在赋值运算符重载中不起作用?

class One
{
    public:
        One(int a1, int b1) {  
            a = a1; b = b1; 
        }

        int a;
        int b;
        One operator=( const One&  obj) { 
            cout<<"\nOperator= is called\n"; a = obj.a; b = obj.b; 
        }
};


int main()
{
    One o1(5,5);
    One o2(10,10);
    One o3(15,15);

    cout << "\no1.a=" << o1.a << ", o1.b=" << o1.b << endl;

    o1 = o2 = o3;

    cout << "\no1.a=" <<o1.a << ", o1.b=" << o1.b << endl;
    cout << "\no2.a=" <<o2.a << ", o2.b=" << o2.b << endl;
    cout << "\no3.a=" <<o3.a << ", o3.b=" << o3.b << endl;


    return 0;
}

输出:

o1.a=-13360, o1.b=0

o2.a=15, o2.b=15

o3.a=15, o3.b=15

为什么o1对象在赋值运算符中按值返回时显示垃圾值。通过引用返回时它工作正常。为什么呢?

3 个答案:

答案 0 :(得分:2)

o1 = o2 = o3;评估为o1 = (o2 = o3);

这需要o2 = o3 返回某些内容,o1设置为该值。但是你的超载目前没有。 (形式上,这意味着代码的行为未定义)。如果你改写为

 One& operator=(const One& obj)
 {
     std::cout << "\nOperator= is called\n";
     a = obj.a;
     b = obj.b;
     return *this; // i.e. return a reference to self.
 }
然后一切都会好的。也就是说,酷猫会使用

 One& operator=(One obj/*pass by value to exploit compiler optimisations*/)
 {
     std::cout << "\nOperator= is called\n";
     std::swap(*this, obj);
     return *this;
 }

参考:What is the copy-and-swap idiom?

答案 1 :(得分:1)

=运算符的代码应为:

One & operator=(const One&  obj)
{
  cout << "\nOperator= is called\n";
  a = obj.a;
  b = obj.b;
  return *this;
}

答案 2 :(得分:0)

 One operator=( const One&  obj)
 { cout<<"\nOperator= is called\n"; a = obj.a; b = obj.b; }

您的函数定义中没有任何返回表达式,导致未定义的行为。这就是为什么操作员不能正常工作的原因。

如果您使用gcc编译器,我建议您启用-Wall选项,该选项会产生警告,指示失败。如果你使用的是不同的,可能还有一个等效选项。

您可能还想查看Copy-and-Swap Idiom,它提供了创建正确工作的复制赋值运算符的高级见解。