Здравствуйте, sanx, Вы писали:
S>С точки зрения правильного C++, при проектировании класса нужно относиться к move семантике как к деструктору, в том смысле что старый объект разрушается, правильно ли?
Нет. Посмотри, например, что происходит в стандартной библиотеке — практически все объекты просто оказываются в "valid but unspecified state". Это совсем не разрушение. Так вектор, из которого произошло перемещение, можно вполне продолжать использовать дальше (хотя, почти всегда сначала следует вызвать метод .clear, чтобы перевести его в "specified state"). И если вектор после move обладал каким-то зарезервированным участком памяти, то он так и останется им владеть — соответствующая память будет освобождена только в деструкторе.
Соответственно, нормальная практика — это ожидать, что объекты после перемещения останутся в "valid but unspecified state". И самому писать код так, чтобы это постусловие для классов выполнялось.
S>Например такая ситуация: класс реализует долгую операцию, и содержит поля используемые в этой операции. Как быть если кто-то захочет сделать move из другого потока?
А если кто-то захочет скопировать объект? А если кто-то захочет вызвать у него какой-нибудь метод? Почему именно перемещение рассматриваешь так особенно, а не более частые ситуации?
К этим проблемам move ничего не добавляет нового.
S>Запретить move семантику для класса? Кидать исключение?
Предлагаю запретить вызывать методы класса, кидать исключении при копировании. А для move можно и посложнее прикол придумать
А если серьёзно, то делай как и у других методов сделано. Если класс объявлен не thread-safe, то ничего. Если копирование происходит под мьютексом, то и перемещение пусть будет под ним же. Кидаешь исключения при обнаружении доступа из разных потоков? Ну тогда кидай их отовсюду.