unique_ptr, переместить конструктор и почему всегда пытаться получить доступ к приватному члену

Я часто сталкиваюсь с этой проблемой, и я считаю, что конструктор перемещения в порядке, но я думаю, что конструктор копирования — это проблема, и его скрытие, похоже, не работает.

Код:

template <class T>
class LinkedList{
public:
//
LinkedList() {}
LinkedList(const T &data);
LinkedList(const T &data, const LinkedList &node);
LinkedList(const LinkedList &object);
LinkedList &operator=(const LinkedList &object);

~LinkedList() {}

std::shared_ptr<LinkedList> push_back(const T& data);

private:
T data;
std::unique_ptr<LinkedList> link;

std::unique_ptr<LinkedList> LinkFactory(const LinkedList &node);

std::shared_ptr<LinkedList> CreateStartNode(const T &data);
std::shared_ptr<LinkedList> CreateNode(const T &data, const LinkedList &node);
};

Конкретная строка, где происходит ошибка:

LinkedList<T>::LinkedList(const LinkedList<T> &object) : data(object.data),
link(std::move(object.link)) {}

Я пытаюсь переместить, а не скопировать, ссылку в конструкторе копирования, но безрезультатно. Если конструктор перемещения разработан, а не синтезирован, будет ли это лучше?

1

Решение

Вы не можете перемещать постоянный объект, и так как object объявлен const, object.link также является постоянным.

Это похоже на сломанный дизайн, так как обычно этот конструктор копия конструктор, но вы пытаетесь переехать ссылка вне параметра, то есть вы пытаетесь украсть принадлежащие ему ресурсы. У вас есть метод LinkFactory, похоже, вы должны использовать его, если он делает то, что обещает название.

5

Другие решения

Конструктор, принимающий lvalue ссылка — это конструктор копирования, а не конструктор перемещения. Если ссылка const то не может изменить существующий объект, и поэтому не может отойти от него. (Вы не должны удалять const, поскольку это дало бы вам странную семантику деструктивного копирования, и семантика перемещения была добавлена ​​к языку, чтобы избежать такой странности).

Ваш класс не может быть скопирован из-за unique_ptr члены, так что вы не должны предоставлять конструктор копирования вообще. Вы можете предоставить конструктор перемещения:

LinkedList<T>::LinkedList(LinkedList<T> && object) :
data(object.data), link(std::move(object.link)) {}

но в этом нет необходимости, поскольку неявно сгенерированный конструктор перемещения делает это (единственное отличие состоит в том, что данные перемещаются, а не копируются).

Помните, что обычно именованные переменные не могут быть перемещены, если вы не сделаете это явно:

LinkedList<int> l1;
LinkedList<int> l2(l1);             // ERROR: tries to copy
LinkedList<int> l3(std::move(l1));  // OK: explicit move
3

Какую семантику вы пытаетесь достичь? В вашем экземпляре
конструктор, копируемый объект const (который
обычно правильно); попытка переместить что-либо в это потребовало бы этого
быть неконстантным. Это выглядит как недостаток дизайна, но если нет,
сделать ссылку mutable может быть ответ.

0

Я определил свой конструктор копирования следующим образом, и у меня нет ошибок времени компиляции или ссылки при использовании unique_ptr:

LinkedList<T>::LinkedList(const LinkedList &other){
data = other.data;
link(std::move(other.link.get()));
}

Я благодарю всех за ответ на этот вопрос.

0
По вопросам рекламы [email protected]