C ++拷贝构造函数行为

时间:2014-01-01 23:02:33

标签: c++ constructor copy variable-assignment

我不太了解C ++代码的一部分。 另外我不知道在哪里可以搜索有关它的信息,所以我决定提问。

#include <iostream>
#include <string>

using namespace std;

class Test
{
    public:
        Test();
        Test(Test const & src);
        Test& operator=(const Test& rhs);
        Test test();
        int x;
};

Test::Test()
{
    cout << "Constructor has been called" << endl;
}

Test::Test(Test const & src)
{
    cout << "Copy constructor has been called" << endl;
}

Test& Test::operator=(const Test& rhs)
{
    cout << "Assignment operator" << endl;
}

Test Test::test()
{
    return Test();
}

int main()
{
    Test a;
    Test b = a.test();

    return 0;
}

为什么我得到的输入是

Constructor has been called
Constructor has been called

? a.test()通过调用“Test()”创建一个新实例,这就是显示第二条消息的原因。但为什么没有复制构造函数或赋值? 如果我将“return Test()”更改为“return *(new Test())”,则调用复制构造函数。

那为什么不是第一次叫它?

2 个答案:

答案 0 :(得分:3)

编译器非常聪明。两份副本 - 从test返回并初始化b(不是这不是作业) - 根据以下规则(C ++11§12.8)被删除:

  

当一个未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过直接构造临时对象来省略复制/移动操作进入省略的复制/移动目标

即使编译器会改变程序的行为(比如删除输出消息),也允许编译器执行此操作。预计您不会编写具有其他副作用的复制/移动构造函数和赋值运算符。

请注意,只有四种情况中的一种可以发生复制省略(不计算as-if规则)。

答案 1 :(得分:-2)

对a.test()的调用按值返回,然后将该值赋给b“复制”返回值。这将调用复制构造函数。