C ++拷贝构造函数的行为[副本](C++ copy constructor behaviour [

2019-10-19 04:39发布

这个问题已经在这里有一个答案:

  • 什么是复制省略和返回值优化? 4个回答

还有就是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()调用创建一个新的实例“测试()”,所以这就是为什么显示第二个消息。 但是,为什么没有拷贝构造函数或赋值叫什么名字? 如果我改变“回归测试()”到“回归*(新测试())”,然后拷贝构造函数被调用。

那么,为什么不叫第一次?

Answer 1:

编译器是很聪明的。 两个副本-从返回test和初始化b (未这不是一个分配) -是根据下面的规则(C ++ 11§12.8)消隐:

当尚未结合至参考(12.2)将被复制临时类对象/移动到具有相同的CV-非限定类型的一类对象中,复制/移动操作可以通过直接构建临时对象到目标被省略的省略复制/移动

编译器允许这样做,即使它会改变(如消除您的输出消息)你的程序的行为。 它的预期,你不写复制/移动构造函数和赋值运算符产生其他副作用。

请注意,只有四个案件中,复制可能会出现省音(不计算为,如果规则)之一。



Answer 2:

该呼叫通过值a.test()返回时,然后该值被分配给b“复制”的返回值。 这将调用拷贝构造函数。



文章来源: C++ copy constructor behaviour [duplicate]