移动构造函数和移动赋值
Move Constructor & Move Assignment
我一直在阅读Bjarne Stroustrup(C 的创建者)的" C 编程语言第4版"一书,并且一直在学习有关移动构造函数和移动作业的了解。
在班级矢量的书中(请参阅下面的标题),他显示了如何实现移动构造函数(请参见下面的2),并说移动分配是以类似的方式实现的,但没有显示如何进行。我自己已经实施了移动任务(请参见下面的3),但一切似乎都很好,但是,我不确定我是否正确实施了。
我没有遇到任何错误,并且已经查看了许多示例,但是我无法确认它是否正确的特定班级。有人可以接受C 的经验,请查看我的代码并发表评论,如果正确?
编辑:另外,请参见4有关构造函数和驱动器。
谢谢您的时间。
P.S:欢迎任何有用的提示或修改
1)类标头文件:
#ifndef VECTOR_H
#define VECTOR_H
#include <cstdlib>
#include <iostream>
#include <stdexcept>
using namespace std;
template<typename T>
class Vector {
public:
// constructors
Vector(int s);
Vector(std::initializer_list<T>);
// destructor
~Vector();
// copy constructor and copy assignment
Vector(Vector&);
Vector<T>& operator=(Vector&);
// move constructor and move assignment
Vector(Vector&&);
Vector<T>& operator=(Vector&&);
// operators
T& operator[](int);
const T& operator[](int) const; // the second const means that this function cannot change the state of the class
// we define operator[] the second time for vectors containing constant members;
// accessors
int getSize();
private:
int size;
T* elements;
};
#endif /* VECTOR_H */
2)移动构造函数(以与书相同的方式实现):
// move constructor
template<typename T>
Vector<T>::Vector(Vector&& moveme) : size{moveme.size}, elements{moveme.elements}
{
moveme.elements = nullptr;
moveme.size = 0;
}
3)移动分配(不确定是否正确):
// move assignment
template<typename T>
Vector<T>& Vector<T>::operator=(Vector&& moveme)
{
delete[] elements; // delete old values
elements = moveme.elements;
size = moveme.size;
moveme.elements = nullptr;
moveme.size = 0;
return *this;
}
4)构造函数和破坏者:
#include <array>
#include "Vector.h"
// constructors
template<typename T>
Vector<T>::Vector(int s) {
if(s<0) throw length_error{"Vector::Vector(int s)"};
// TODO: use Negative_size{} after learning how to write custom exceptions
this->size = s;
this->elements = new T[s];
}
template<typename T>
Vector<T>::Vector(std::initializer_list<T> list) : size(list.size()),
elements(new T[list.size()])
{
copy(list.begin(), list.end(), elements);
}
// destructor
template<typename T>
Vector<T>::~Vector()
{
delete[] this->elements;
}
因为在评论中回答了这个问题,我认为我会遵循元的建议:没有答案的问题,但是在评论中解决的问题(或在聊天中扩展)并写入书写一个简短的社区Wiki可以关闭并回答问题。
我还将添加有用的其他信息和其他用户的提示,这些用户在评论中加入讨论。
bo presson回答并提供有关模板放置的其他信息:
移动分配似乎是合理的,除了将模板放入 CPP文件只能在该CPP文件中使用。看 为什么仅在标题文件中实现模板?
rakete1111阐明我对移动语义的误解:
std :: move!=移动语义。您有移动语义,rvalues 可以移动(使用移动构造函数)而不是复制。std ::移动 只是启用移动语义的设施(例如使用移动 constructor)对于不是rvalues的类型。
KIM366与Jive Dadson提出回报优化问题,我回答:
...另外,如果您没有 移动CTOR/分配超载吗?-kim366
似乎是如此,在示例中(请参见下面的功能),他说
z = x + y + z
将两次复制返回结果。 10,000双打,这可能令人尴尬。"但是,鉴于这一点 定义,编译器将选择移动构造函数以实现 回报价值的转移..."他发明了C ,所以请服用 他的话:)。Vector operator+(const Vector& a, const Vector& b) { if (a.size()!=b.size()) throw Vector_size_mismatch{}; Vector res(a.size()); for (int i=0; i!=a.size(); ++i) res[i]=a[i]+b[i]; return res; }
-Hammeramr(示例来自书籍:" C 编程语言第四版" 由Bjarne Stroustrup )
另请参阅 什么是拷贝和交换成语? -Jive Dadson
希望人们发现这有用,并感谢参加的人。
- 移动赋值运算符;尝试引用已删除的函数.我该如何解决这个问题?
- 对 r 值使用移动赋值运算符时的异常
- 移动构造函数与移动赋值
- 为什么定义移动构造函数会删除移动赋值运算符
- C++中移动赋值运算符的继承
- 从自身内部替换 std::函数(通过将移动赋值到 *this?)
- 为什么对象可以"moved"甚至缺少移动构造函数和移动赋值运算符?
- 移动赋值运算符与复制赋值运算符
- 查找所有移动构造函数和移动赋值运算符(特别是那些没有"noexcept"的运算符)
- 移动构造函数和移动赋值运算符与复制省略
- CRTP 和复制/移动赋值/构造函数继承
- 在原始对象上使用惯用(例如 TBB 的 thread_enumerable_specific')移动赋值调用析构函数
- 未隐式声明的移动赋值运算符
- 如何使用继承(抽象基类)实现移动构造函数和移动赋值运算符
- 移动构造函数和移动赋值
- 未调用移动赋值运算符
- 移动赋值运算符和移动构造函数之间的区别
- 为什么同时使用一个赋值运算符处理复制和移动赋值效率不高
- 我应该删除智能指针的移动构造函数和移动赋值吗
- 如果成员具有非平凡的noexcept赋值运算符,则默认的移动赋值不能显式为noexcept