[英]Move Constructor & Move Assignment
I have been reading the book "The C++ programing language 4th edition" by Bjarne Stroustrup (The creator of c++) and have been learning about move constructors and move assignments. 我一直在阅读Bjarne Stroustrup(c ++的创建者)的“The C ++ programing language 4th edition”一书,并且一直在学习移动构造函数和移动赋值。
In the book for the class vector (see 1 for header below) he shows how to implement the move constructor (see 2 below) and says the move assignment is implemented in a similar manner but doesn't show how. 在类向量的书中(参见下面的标题1),他展示了如何实现移动构造函数(见下面的2),并说移动赋值是以类似的方式实现的,但没有说明如何实现。 I have implemented the move assignment myself (see 3 below) and everything seems to be working fine, however, I am not sure I have implemented it correctly.
我自己实现了移动任务(见下面的3),一切似乎工作正常,但是,我不确定我是否正确实现了它。
I am not getting any errors and have looked at many examples but I cannot confirm its correct for my specific class. 我没有得到任何错误,并查看了许多示例,但我无法确认它对我的特定课程是否正确。 Can someone experienced with c++ please look at my code and comment if it is correct?
有人可以使用c ++,请查看我的代码并评论是否正确?
EDIT: Also please see 4 for constructors and destructor. 编辑:另请参阅4的构造函数和析构函数。
Thank you for your time. 感谢您的时间。
PS: Any helpful hints or modifications are welcome PS:欢迎任何有用的提示或修改
1) Class Header File: 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 (implemented in the same way as book): 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 (not sure if correct): 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) Constructors and destructor: 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;
}
Since this question was answered in the comments I thought I'd follow the advice from the meta: Question with no answers, but issue solved in the comments (or extended in chat) and write a short Community Wiki to close and answer the question. 由于这个问题在评论中被回答,我认为我会遵循meta的建议: 没有答案的问题,但问题在评论中得到解决(或在聊天中扩展)并编写一个简短的社区Wiki来关闭并回答问题。
I will also add useful additional info and tips from other users who joined the discussion in the comments. 我还将添加来自评论中加入讨论的其他用户的有用的其他信息和提示。
Bo Presson answering and providing additional info on template placement: Bo Presson回答并提供有关模板放置的其他信息:
The move assignment seems reasonable, except that putting templates in a cpp file makes them usable in that cpp file only.
移动分配似乎是合理的,除了将模板放在cpp文件中使它们仅在该cpp文件中可用。 See Why can templates only be implemented in the header file?
请参阅为什么模板只能在头文件中实现?
Rakete1111 clarifying a misconception I had regarding move semantics: Rakete1111澄清了我对移动语义的误解:
std::move != move semantics.
std :: move!=移动语义。 You have move semantics, where rvalues can be moved (using the move constructor) instead of copied.
你有移动语义,可以移动rvalues(使用移动构造函数)而不是复制。 std::move is just a facility to enable move semantics (like using the move constructor) for types that are not rvalues.
std :: move只是一个为非rvalues类型启用移动语义(如使用移动构造函数)的工具。
kim366 bringing up return optimization question with Jive Dadson and I answering: kim366与Jive Dadson提出了返回优化问题,我回答:
... Also, is there really no return-value-optimization, if you don't have overloaded move ctors/assignments ?
...此外,如果您没有超载的移动/分配,是否真的没有返回值优化? -kim366
-kim366
It seems so, in the example (see function below) he says that
z = x + y + z
will copy the return result twice "If a Vector is large, say, 10,000 doubles, that could be embarrassing."看起来如此,在示例中(参见下面的函数),他说
z = x + y + z
会将返回结果复制两次“如果一个Vector很大,比如10,000个双打,那可能会令人尴尬。” But "Given that definition, the compiler will choose the move constructor to implement the transfer of the return value..." He invented c++ so ill just take his word for it :).但是“鉴于这个定义,编译器将选择移动构造函数来实现返回值的传递......”他发明了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; }
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; }
- hammeramrVector 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(Example was from the book: "The C++ programing language 4th edition" by Bjarne Stroustrup )
(例子来自Bjarne Stroustrup的书“C ++编程语言第4版” )
See also What is the copy-and-swap idiom?
另请参见什么是复制和交换习惯用法? -Jive Dadson
-Jive Dadson
Hope people find this useful and thanks for those who participated. 希望人们觉得这很有用,并感谢参与者。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.