gpt4 book ai didi

c++ - C++中的移动构造函数和复制构造函数

转载 作者:太空狗 更新时间:2023-10-29 20:01:53 25 4
gpt4 key购买 nike

我的理解是,当我们从函数返回局部对象时,如果移动构造函数存在,它就会被调用。但是,我遇到了调用复制构造函数的情况,如下面函数 foo2() 中的示例所示。为什么会这样?

#include <cstdio>
#include <memory>
#include <thread>
#include <chrono>

class tNode
{
public:
tNode(int b = 10)
{
a = b;
printf("a: %d, default constructor %s() is called at %s:%d \n", a, __func__, __FILE__, __LINE__);
}

tNode(const tNode& node)
{
a = node.a;
printf("a: %d, copy constructor %s() is called at %s:%d \n", a, __func__, __FILE__, __LINE__);
}

tNode& operator=(const tNode& node)
{
a = node.a;
printf("a: %d, copy assignment %s() is called at %s:%d \n", a, __func__, __FILE__, __LINE__);
}

tNode(tNode&& node)
{
a = node.a;
printf("a: %d, move constructor %s() is called at %s:%d \n", a, __func__, __FILE__, __LINE__);
}

tNode& operator=(tNode&& node)
{
a = node.a;
printf("a: %d, move assignment %s() is called at %s:%d \n", a, __func__, __FILE__, __LINE__);
}

~tNode() { printf("a: %d, destructor %s() is called at %s:%d \n", a, __func__, __FILE__, __LINE__); }

private:
int a = 0;
};

tNode foo()
{
tNode node;
return node;
}

tNode foo2()
{
std::unique_ptr<tNode> up = std::make_unique<tNode>(20);
return *up;
}

int main()
{
{
tNode n1 = foo();
tNode n2 = foo2();
}

// we pause here to watch how objects are created, copied/moved, and destroyed.
while (true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}

return 0;
}

上面的代码是用g++ --std=c++17 -fno-elide-constructors编译的输出是:

a: 10, default constructor tNode() is called at testCopyControl.cpp:13
a: 10, move constructor tNode() is called at testCopyControl.cpp:31
a: 10, destructor ~tNode() is called at testCopyControl.cpp:40
a: 10, move constructor tNode() is called at testCopyControl.cpp:31
a: 10, destructor ~tNode() is called at testCopyControl.cpp:40
a: 20, default constructor tNode() is called at testCopyControl.cpp:13
a: 20, copy constructor tNode() is called at testCopyControl.cpp:19
a: 20, destructor ~tNode() is called at testCopyControl.cpp:40
a: 20, move constructor tNode() is called at testCopyControl.cpp:31
a: 20, destructor ~tNode() is called at testCopyControl.cpp:40
a: 20, destructor ~tNode() is called at testCopyControl.cpp:40
a: 10, destructor ~tNode() is called at testCopyControl.cpp:40

从输出中,我们知道当foo2()返回*up时调用了一个拷贝构造函数来初始化一个临时的tNode对象;为什么没有调用移动构造函数?

最佳答案

tNode foo()
{
tNode node;
return node;
}

tNode n1 = foo();

负责输出

a: 10,  tNode() is called at testCopyControl.cpp:13
a: 10, move constructor tNode() is called at testCopyControl.cpp:31
a: 10, destructor ~tNode() is called at testCopyControl.cpp:40
a: 10, move constructor tNode() is called at testCopyControl.cpp:31
a: 10, destructor ~tNode() is called at testCopyControl.cpp:40

您看到的是默认构造函数被调用,然后 node 开始在 return 语句中被视为右值以将其移动到返回值中,然后从返回值移动到 n1

tNode foo2()
{
std::unique_ptr<tNode> up = std::make_unique<tNode>(20);
return *up;
}

行为不同,因为您没有返回函数局部对象。 *up 为您提供了一个 tNode&,因此 return 语句不能将其视为右值。因为它是一个左值,所以你必须调用复制构造函数将它复制到返回值中。然后,与第一个示例一样,调用移动构造函数将对象从返回值移动到 n2

关于c++ - C++中的移动构造函数和复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50375451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com