Является ли совместная реализация памяти / копии при записи для обычных контейнеров (например, из контейнеров Qt) замененной C ++ 11 семантикой перемещения и ссылками на rvalue?
Где один провалится, а другой преуспеет? Или они дополняют, а не альтернативы?
Семантика копирования при записи и перемещения использовалась для оптимизации семантики значений объектов, которые хранят свои данные в куче. std::string
Например, был реализован как объект копирования при записи, а также как объект с возможностью перемещения.
Таким образом, семантика копирования при записи и перемещения аналогична в этом отношении: их можно использовать для оптимизации «копий», если вы достаточно свободно определяете «копировать». Я иногда описывал семантику перемещения как копирование при записи, при этом счетчик ссылок был ограничен 0 или 1, и поэтому поле, содержащее счетчик ссылок, оптимизировалось.
Все контейнеры в std :: lib теперь используют семантику перемещения и даже std::string
, которому раньше разрешалось использовать копирование при записи, теперь запрещено делать это. Если бы я писал новый контейнер клиента сегодня, я бы использовал семантику перемещения, прежде чем выбирать копирование при записи.
В C ++ 11 все еще используется копирование при записи. Если вы ожидаете, что ваша структура данных будет редко записываться, но часто копироваться, поскольку многие клиенты хранят копии с одинаковым значением, копирование при записи может все же стать большим выигрышем.
Например, я видел, как копирование при записи находило хорошее применение для хранения списка отмен для сложного документа. В любой данный коммит (где вы хотите сохранить состояние) только маленький фрагмент большого документа изменился с момента последнего коммита. Таким образом, создание копии документа для сохранения его состояния означает обновление набора ссылок и фактическое внесение изменений (стиль копирования при записи) в небольшой фрагмент.
Семантика копирования при записи и перемещения — это совершенно разные концепции, каждая из которых служит своей цели. Хотя есть общий вариант использования: возвращение объекта из функции, в которой потому что оригинал выходит за рамки это фактически ход, в общем случае они отличаются:
С копировать на запись несколько объектов, которые являются живыми одновременно, могут доля содержимое. В семантике перемещения только один объект имеет содержимое в определенный момент времени.
Немного ортогонально этому, при копировании при записи возникают проблемы в многопоточных средах, поскольку потенциально существует несколько объектов, обращающихся к одним и тем же данным (только для чтения) и блоку управления (чтение / запись), которым необходимо управлять потокобезопасным способом ,