Я читал книгу Бьярна Страуструпа (создатель c ++) «4-й выпуск языка программирования C ++» и изучал конструкторы и назначения перемещений.
В книге для вектора класса (см. 1 для заголовка ниже) он показывает, как реализовать конструктор перемещения (см. 2 ниже), и говорит, что назначение перемещения реализовано аналогичным образом, но не показывает, как. Я сам выполнил назначение перемещения (см. 3 ниже), и все, кажется, работает нормально, однако я не уверен, что выполнил это правильно.
Я не получаю никаких ошибок и посмотрел на многих примерах, но я не могу подтвердить его правильность для моего конкретного класса. Может кто-то имел опыт работы с c ++, пожалуйста, посмотрите на мой код и прокомментируйте, если он правильный?
РЕДАКТИРОВАТЬ: Также см. 4 для конструкторов и деструкторов.
Спасибо за ваше время.
П.С .: Любые полезные советы или модификации приветствуются
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;
}
Поскольку на этот вопрос ответили в комментариях, я подумал, что последую совету мета: Вопрос без ответов, но проблема решена в комментариях (или расширена в чате) и написать короткую вики-страницу сообщества, чтобы закрыть и ответить на вопрос.
Я также добавлю полезную дополнительную информацию и советы от других пользователей, которые присоединились к обсуждению в комментариях.
Бо Прессон ответ и предоставление дополнительной информации о размещении шаблона:
Назначение перемещения кажется разумным, за исключением того, что
cpp-файл делает их пригодными для использования только в этом cpp-файле. Увидеть
Почему шаблоны могут быть реализованы только в заголовочном файле?
Rakete1111 прояснение неправильного представления о семантике перемещения:
std :: move! = семантика перемещения У вас есть семантика перемещения, где значения
может быть перемещен (используя конструктор перемещения) вместо копирования. станд :: ход
это просто средство для включения семантики перемещения (например, использование перемещения
конструктор) для типов, которые не являются значениями.
kim366 поднимая вопрос оптимизации возврата с Джайв Дадсон и я отвечаю:
… Кроме того, действительно ли нет никакой оптимизации возвращаемого значения, если вы этого не сделаете
есть перегруженные двигатели / задания? -kim366Кажется, что в примере (см. Функцию ниже) он говорит, что
z = x +
будет скопировать возвращаемый результат дважды «Если вектор большой, скажем,
y + z
10000 удваивается, это может быть неловко. «Но» Учитывая, что
определение, компилятор выберет конструктор перемещения для реализации
передача возвращаемого значения … «Он придумал 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; }(Пример был из книги: «Брэйн Страуструп», 4-е издание, язык программирования C ++)
Смотрите также
Что такое идиома копирования и обмена?
-Джайв Дадсон
Надеюсь, что люди найдут это полезным и спасибо за тех, кто принял участие.
Других решений пока нет …