C++ 复制构造函数行为

标签 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())”,则会调用复制构造函数。

那为什么不是第一次调用呢?

最佳答案

编译器非常聪明。两个拷贝——从 test 返回并初始化 b(这不是赋值)——根据以下规则 (C++11 §12.8) 被省略:

when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move

即使这会改变程序的行为(比如删除输出消息),编译器也可以这样做。希望您不要编写具有其他副作用的复制/移动构造函数和赋值运算符。

请注意,这只是可能发生复制省略的四种情况之一(不包括 as-if 规则)。

关于C++ 复制构造函数行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20874193/

相关文章:

c++ - 在没有宏的情况下推断类型同时省略移动/复制

C++:复制到解除引用的指针

php - 使用 PHP 从远程服务器复制 JPG 文件的首选方法

c++ - QML:多次按下/释放后某些键未处理

c++ - Windows Phone 8 上的 DirectX - 上下文/设备在最小化时丢失

c++ - 如何从 C++ 中选择 TableView (qml) 中的行?

c++ - 什么时候不能将对象转换为引用?

java - 为什么有些带参数的构造函数仍然调用this()?好像什么也没做?

java - 构造函数重载 - Java 最佳实践

c++ - 属于对象的指针会发生什么情况,其拷贝被推送到 vector?