Здравствуйте, 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. Что-то еще
Например, дополнительный флаг в объекте «я_мёртв».
Но, в общем, первые два варианта самые подходящие. И если так уж не доверяешь пользователю обёртки, то выбирай реализацию через указатели.