了解函数返回对象的移动语义
Understanding move semantics with objects returned by a function
我从 learncpp.com 遇到了以下程序,作为理解移动语义的示例。我尝试运行此程序,并按照教程中的说明查看程序流的工作方式。
但是,我在函数调用中无法理解它。
Auto_ptr4<Resource> generateResource()
{
Auto_ptr4<Resource> res(new Resource);
return res; // this return value will invoke the move constructor
}
据说将使用移动构造函数,但是当我设置断点并进行调试时,它根本没有这样做。
谁能帮助我理解为什么这里不调用移动构造函数?编译器会在这里省略吗?如果是这样,如何修改它以便它将调用移动构造函数。请解释一下这里发生了什么。
此外,如果您可以分享一些调用移动构造函数以及如何使用移动构造函数代替复制构造函数的示例,那就太好了。
#include <iostream>
template<class T>
class Auto_ptr4
{
T* m_ptr;
public:
Auto_ptr4(T* ptr = nullptr)
:m_ptr(ptr)
{
}
~Auto_ptr4()
{
delete m_ptr;
}
// Copy constructor
// Do deep copy of a.m_ptr to m_ptr
Auto_ptr4(const Auto_ptr4& a)
{
m_ptr = new T;
*m_ptr = *a.m_ptr;
}
// Move constructor
// Transfer ownership of a.m_mptr to m_ptr
Auto_ptr4(Auto_ptr4&& a)
: m_ptr(a.m_ptr)
{
a.m_ptr = nullptr;
}
// Copy assignment
// Do deep copy of a.m_ptr to m_ptr
Auto_ptr4& operator=(const Auto_ptr4& a)
{
// Self-assignment detection
if (&a == this)
return *this;
// Release any resource we're holding
delete m_ptr;
// Copy the resource
m_ptr = new T;
*m_ptr = *a.m_ptr;
return *this;
}
// Move assignment
// Transfer ownership of a.m_ptr to m_ptr
Auto_ptr4& operator=(Auto_ptr4&& a)
{
// Self-assignment detection
if (&a == this)
return *this;
// Release any resource we're holding
delete m_ptr;
// Transfer ownership of a.m_ptr to m_ptr
m_ptr = a.m_ptr;
a.m_ptr = nullptr;
return *this;
}
T& operator*() const { return *m_ptr; }
T* operator->() const { return m_ptr; }
bool isNull() const { return m_ptr == nullptr; }
};
class Resource
{
public:
Resource() { std::cout << "Resource acquiredn"; }
~Resource() { std::cout << "Resource destroyedn"; }
};
Auto_ptr4<Resource> generateResource()
{
Auto_ptr4<Resource> res(new Resource);
return res; // this return value will invoke the move constructor
}
int main()
{
Auto_ptr4<Resource> mainres;
mainres = generateResource(); // this assignment will invoke the move assignment
return 0;
}
谢谢
Auto_ptr4<Resource> generateResource()
{
Auto_ptr4<Resource> res(new Resource);
return res; // this return value will invoke the move constructor
}
您的代码编写方式非常允许复制省略。C++标准有一整节专门讨论这个用例。
[class.copy.elision/1.1]
在具有类返回类型的函数的 return 语句中,当表达式是与函数返回类型相同类型(忽略 CV 限定)的非易失性自动对象(函数参数或处理程序的异常声明 ([except.handle])引入的变量除外)的名称时,可以通过将自动对象直接构造到函数调用的返回对象中来省略复制/移动操作
如果要防止省略,则需要返回一个不能合法省略的表达式。幸运的是,在这种情况下,强制调用移动构造函数也相当容易:
Auto_ptr4<Resource> generateResource()
{
Auto_ptr4<Resource> res(new Resource);
return std::move(res); // this return value will invoke the move constructor
}
由于现在表达式不是自动变量名,Auto_ptr4<Resource>&&
也不完全相同Auto_ptr4<Resource>
.c'tor 没有被省略。
这对于学习目的很好,但不要在实际代码中执行此操作。复制省略是一件非常好的事情,它可以提高代码的效率。让编译器在可能的情况下为您完成。
相关文章:
- 何时在引用或唯一指针上使用移动语义
- 如何从具有移动语义的类对象中生成共享指针
- 可以使用移动语义更改或改进此C++代码吗?
- c++在使用指针时移动语义
- 移动语义和深层/浅层复制之间有什么关系?
- std::unique_lock移动语义
- 移动语义和运算符 + 重载
- C++ 移动语义是否在任何情况下都能节省资源?
- 移动语义在这里如何工作?
- 使用移动语义:右值引用作为方法参数
- 在C++中使用移动语义的正确方法是什么?
- 移动语义 c++ 单链表
- C++:使用整数移动语义
- 当变量和参数名称匹配时,移动语义构造失败
- 在 C++11 中移动语义
- 方法冗余移动调用的移动语义
- 复制省略并在返回值中移动语义
- std::元组和移动语义
- 移动语义与返回shared_ptr?
- C++具有移动语义的可变参数工厂会导致运行时崩溃