根据我的理解,下面的代码应该调用 Test
类的 move 构造函数,因为这个函数按值返回,这意味着表达式 GetTestObj()
应该是右值,xvalues 是隐式的 move 但为什么这段代码调用复制构造函数?
class Test
{
public:
Test()
{
}
Test(const Test& arg)
{
std::cout<<"Copy Constructor Called..."<<std::endl;
}
Test(Test&& arg)
{
std::cout<<"Move Constructor Called..."<<std::endl;
}
};
Test GetMyTestObj()
{
Test *ptr = new Test();
return *ptr;
}
Test dummy = GetMyTestObj(); //Copy Constructor Called...
最佳答案
在您的代码中,实际上有一个拷贝从 *ptr
到返回值,还有一个从 GetMyTestObj()
到 dummy
。但是,编译器 elides move ,所以你不会看到它被跟踪。如果您将 -fno-elide-constructors
传递给 GCC 或 Clang,那么您应该会看到拷贝和 move (demo)。
如果要将返回值构造为move,需要使用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{};
关于c++ - 按值返回的函数的值类别是否总是 xvalue?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40460746/