Re: Ссылки и move semantics
От: watchmaker  
Дата: 24.07.15 12:57
Оценка:
Здравствуйте, Videoman, Вы писали:

V>В процессе реализации move конструктора возник вопрос который интернет "тактично" обходит.

Как же так? Задаёшь поисковику запрос «Reference data members and move constructor» и изучаешь.

V>Есть некая обертка, которая принимает ссылку на некий объект. Обертка не копируется и рассчитана на работу только в текущей области видимости. Теперь допустим мне необходимо создать вектор оберток. При создании вектора как раз и используется move конструктор.


V>Теперь проблема: при перемещении членов обертки, внутри конструктора, ссылку занулить невозможно.

Так и требования чего-то там занулять в move-конструкторе нет. После его работы экземпляр-источник должен остаться в консинстентном состоянии. Например, move-конструктор иногда через swap реализуется — очевидно тут два объекта просто меняются данными, а не зануляют что-то. Так и наличие ссылки в экземпляр-источнике на какой-то объект само по себе не приведёт проблемам пока, как ты заметил, через эту ссылку с объектом не начнут работать несогласованно из нескольких мест.

V>Что смущает:

V>После перемещения, теоретически, можно нечаянно через методы объекта который уже перемещен изменить объект на который осталась ссылка.
Да, но по сути такой же риск есть и для всех других классов после их перемещения. Наличие ссылки тут не делает проблему новой. Хотя, конечно, если использовать вместо ссылок указатели, то можно присваивать им nullptr и падать в segfault при попытке разыменования, что поможет отладке.

Но лучше просто следовать правилу «не использовать объект после std::move». Нарушил — сам виноват.

V>Какие есть варианты:

V>1. Вместо ссылок использовать указатели
V>2. Забить и оставить валидную ссылку в объекте который уже перемещен
V>3. Что-то еще
Например, дополнительный флаг в объекте «я_мёртв».
Но, в общем, первые два варианта самые подходящие. И если так уж не доверяешь пользователю обёртки, то выбирай реализацию через указатели.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.