Ign*_*ant 1 c++ memory temporary move-semantics c++11
我有一个用RAII编写的Array类(为了这个例子的目的,超简化):
struct Array
{
Array(int size) {
m_size = size;
m_data = new int[m_size];
}
~Array() {
delete[] m_data;
}
int* m_data = nullptr;
int m_size = 0;
};
Run Code Online (Sandbox Code Playgroud)
然后我有一个函数,它接受一个数组的引用并对它进行一些操作.我使用临时数组temp来执行处理,因为有几个原因我不能直接使用引用.完成后,我想将数据从临时数据传输到真实数据:
void function(Array& array)
{
Array temp(array.m_size * 2);
// do heavy processing on `temp`...
array.m_size = temp.m_size;
array.m_data = temp.m_data;
}
Run Code Online (Sandbox Code Playgroud)
显而易见的问题是temp在函数末尾超出范围:它的析构函数被触发,而后者又删除了内存.这种方式array将包含不存在的数据.
那么将数据所有权从一个对象"移动"到另一个对象的最佳方法是什么?
你想要的是为你的数组类移动构造或移动赋值,这可以节省多余的副本.此外,它将帮助您使用std::unique_ptr哪个将为您分配内存的移动语义,因此您不需要自己直接进行任何内存分配.您仍然需要拉起袖子并遵循"零/三/五规则",在我们的例子中是五的规则(复制和移动构造函数,复制和移动赋值运算符,析构函数).
所以,试试:
class Array {
public:
Array(size_t size) : m_size(size) {
m_data = std::make_unique<int[]>(size);
}
Array(const Array& other) : Array(other.size) {
std::copy_n(other.m_data.get(), other.m_size, m_data.get());
}
Array(Array&& other) : m_data(nullptr) {
*this = other;
}
Array& operator=(Array&& other) {
std::swap(m_data, other.m_data);
m_size = other.m_size;
return *this;
}
Array& operator=(const Array& other) {
m_data = std::make_unique<int[]>(other.m_size);
std::copy_n(other.m_data.get(), other.m_size, m_data.get());
return *this;
}
~Array() = default;
std::unique_ptr<int[]> m_data;
size_t m_size;
};
Run Code Online (Sandbox Code Playgroud)
(实际上,拥有m_size和m_data公开是一个坏主意,因为它们被捆绑在一起而你不想让人们搞乱它们.我也会在元素类型上模拟该类,即T代替int和使用Array<int>)
现在,您可以以非常直接的方式实现您的功能:
void function(Array& array)
{
Array temp { array }; // this uses the copy constructor
// do heavy processing on `temp`...
std::swap(array, temp); // a regular assignment would copy
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
572 次 |
| 最近记录: |