c++ - 为什么在这段代码片段中复制构造函数被调用了两次?

标签 c++ c++14 copy-constructor

我正在玩一些东西来了解复制构造函数的工作原理。但是我不明白为什么复制构造函数被调用两次来创建x2。我会假设它会在 createX() 的返回值被复制到 x2 时被调用一次。
我还查看了一些关于 SO 的相关问题,但据我所知,我找不到与我在这里问的相同的简单场景。

顺便说一句,我正在使用 -fno-elide-constructors 进行编译,以便查看没有优化的情况。

#include <iostream>

struct X {
    int i{2};

    X() {
        std::cout << "default constructor called" << std::endl;
    }

    X(const X& other) {
        std::cout << "copy constructor called" << std::endl;
    }
};

X createX() {
    X x;
    std::cout << "created x on the stack" << std::endl;
    return x;
}

int main() {
    X x1;
    std::cout << "created x1" << std::endl;
    std::cout << "x1: " << x1.i << std::endl << std::endl;    

    X x2 = createX();
    std::cout << "created x2" << std::endl;
    std::cout << "x2: " << x2.i << std::endl;    

    return 0;
}

这是输出:

default constructor called
created x1
x1: 2

default constructor called
created x on the stack
copy constructor called
copy constructor called
created x2
x2: 2

有人可以帮我解决我在这里遗漏或忽略的问题吗?

最佳答案

你必须记住的是,函数的返回值是一个不同的对象。当你这样做时

return x;

你用x复制初始化返回值对象。这是您看到的第一个复制构造函数调用。那么

X x2 = createX();

使用返回的对象来复制初始化x2,所以这是您看到的第二个拷贝。


有一点需要注意的是

return x;

如果可以的话,会尝试将 x 移动到返回对象中。如果你做了一个移动构造函数,你会看到这个被调用。这样做的原因是,由于局部对象在函数末尾超出范围,编译器将对象视为右值,只有当它没有找到有效的重载时,它才会回退到将其作为左值返回。

关于c++ - 为什么在这段代码片段中复制构造函数被调用了两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54929274/

相关文章:

c++ - 利用 move 语义自动隐式生成 ctors

c++ - 在 Visual Studio 调试器中,{null=???} 是什么意思?

c++ - 使用模板模板参数作为类函数的返回类型

c++11 - 作为参数和返回类型的通用引用

C++ 候选构造函数不可行 : no known conversion

c++ - 如何 boost::bind 以通用引用作为参数的模板成员函数

C++:当使用从对象的getter方法调用的值时,输出一个随机的负整数?

c++ - 2个默认复制构造函数: is it possible?

c++ - 错误 : type 'std::__1::basic_string<char>' does not provide a call operator

c++ - 调用复制构造函数而不是移动构造函数