分配操作员

时间:2013-11-17 19:43:21

标签: c++ c++11 overloading variable-assignment operator-keyword

关于赋值运算符的工作原理我不明白,请看一下这段代码:

#include <iostream>
using namespace std;

class foo
{
    int val{};
public:
    foo()
    {
    }
    foo( int n )
    {
        val = n;
        cout<<"Constructor"<<endl;
    }
    foo( const foo& f )
    {
        cout<<"Copy constructor, val "<<endl;
        val = f.val;
    }

    foo( const foo&& f )
    {
        cout<<"Copy constructor -rvalue-"<<endl;
        val = f.val;
    }
    foo operator+( const foo& other ) const
    {
        cout<<"Sum "<<endl;
        foo foo2;
        foo2.val = val + other.val;
        return foo2;
    }
    foo& operator=( const foo& f )
    {
        cout<<"Assignment operator\n";
        val = f.val;
        return *this;
    }
    foo& operator=( const foo&& f)
    {
        cout<<"Assignment operator, r-value\n";
        val = f.val;
        return *this;
    }
    ~foo() {}
};

int main()
{
    foo a{1}, b{5}, c{4};
    foo d;
        d = a + b + c;
    foo d2 = a + b + c;
    return 0;
}

此应用程序的输出是:

Constructor
Constructor
Constructor
Sum
Sum
Assignment operator, r-value
Sum
Sum

我不清楚为什么第二个赋值不会触发赋值运算符。第一个赋值是在一个通过默认构造构造的对象上,然后一个普通的赋值操作是可见的,在第二个分配中,一个临时对象应该由编译器构建,然后分配给d2,但是没有任何打印可见。赋值运算符提供。为什么呢?

由于

4 个答案:

答案 0 :(得分:3)

没有第二项任务,您的代码只有一项任务。这条线

foo d2 = a + b + c;

是复制初始化。

答案 1 :(得分:1)

为了效率,这个:

foo d2 = a + b + c;

(以及T n = expr其中T是具有非显式复制构造函数的类型)实际上是

的同义词
foo d2(foo(a + b + c)); // can be optimized to foo d2(a + b + c)

<强>不

foo d2;
d2 = a + b + c;

这就是为什么你只在输出中看到一个作业。

你可以这样想:当变量已经存在时,就是它的赋值。当你创建一个新变量时,它是一个构造函数调用。

答案 2 :(得分:0)

您正在初始化d2,而不是分配给它,因此不会调用赋值运算符。

答案 3 :(得分:0)

第一个是赋值,第二个是初始化。在这种情况下,允许编译器忽略在这种情况下可能发生的复制或移动操作。