根据我的理解,下面的代码应该调用const int MAX_STRING = 256;
类的移动构造函数,因为此函数按值返回,这意味着表达式Test
应该是rvalue并且xvalues被隐式移动但是为什么这个代码是调用copy构造函数?
GetTestObj()
答案 0 :(得分:2)
在您的代码中,实际上有*ptr
的一个副本返回到返回值,另一个从GetMyTestObj()
移动到dummy
。但是,编译器elides移动,所以你不会看到它被跟踪。如果您将-fno-elide-constructors
传递给GCC或Clang,那么您应该看到副本和移动(demo)。
如果您想要将返回值构造为移动,则需要使用std::move
:
Test GetMyTestObj()
{
Test *ptr = new Test();
return std::move(*ptr);
}
但是,在这种情况下,实际上不需要动态分配;它的效率很低,并且会因你的实现而泄漏内存。你应该只使用一个自动变量:
Test GetMyTestObj()
{
Test test;
//I assume you're doing something else here
return test;
}
使用上面的代码,编译器实际上可以忽略这两种结构。
如果你在该功能中没有做任何其他事情,你应该直接构建dummy
:
Test dummy{};
答案 1 :(得分:0)
表示表达式
GetTestObj()
应该是rvalue,xvalues是隐式移动的
首先,直接回答您的问题,GetTestObj()
是prvalue。
- 函数调用或非引用返回类型的重载运算符表达式,例如
str.substr(1, 2)
,str1 + str2
或it++
;
关键是return *ptr;
需要复制/移动操作; ptr
是一个命名变量,它是lvalue。 *ptr
也是左值,无法移动。
您可以明确地使用std::move
使其成为可移动的x值:
return std::move(*ptr);
答案 2 :(得分:0)
值不会复制到此处(由于复制省略而没有调用构造函数):
Test dummy = GetMyTestObj();
但是在这里:
return *ptr;
因为函数必须从左值引用生成rvalue对象。基本上,GetMyTestObj()
函数在这种情况下相当于:
Test *ptr = new Test();
Test returnValue(*ptr);
return returnValue;