【发布时间】:2018-05-16 16:04:45
【问题描述】:
我的理解是,当我们从函数返回本地对象时,如果存在移动构造函数,则会调用它。但是,我遇到了调用复制构造函数的情况,如下面的函数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对象;为什么没有调用移动构造函数?
【问题讨论】:
-
你能缩短你的例子吗?我不敢相信所有这些行都是相关的。
-
我很好奇,为什么要使用
-fno-elide-constructors构建? -
return *up必须复制 -*up不可移动。 -
您的程序引入了未定义的行为。您不会在声明为返回引用的函数中返回引用。
tNode& operator=(const tNode& node)之类的函数——因此无法从您的代码中推测任何内容。 -
@JesperJuhl:大概是为了演示被问及的语言行为?
标签: c++ copy-constructor move-constructor