Мне интересно, какие возможные достоинства есть у копирования при записи? Естественно, я не жду личных мнений, но реальных практических сценариев, где это может быть технически и практически выгодно ощутимым образом. И под осязаемым я имею в виду нечто большее, чем спасение вас от набора &
символов.
Для пояснения этот вопрос относится к типам данных, где конструкция присваивания или копирования создает неявную поверхностную копию, но при ее модификации создается неявная глубокая копия и применяется к ней изменения вместо исходного объекта.
Причина, по которой я спрашиваю, заключается в том, что я не вижу каких-либо преимуществ использования COW в качестве неявного поведения по умолчанию. Я использую Qt, в котором COW реализован для многих типов данных, практически для всех, которые имеют некоторое динамическое распределение памяти. Но как это может принести пользу пользователю?
Пример:
QString s("some text");
QString s1 = s; // now both s and s1 internally use the same resource
qDebug() << s1; // const operation, nothing changes
s1[o] = z; // s1 "detaches" from s, allocates new storage and modifies first character
// s is still "some text"
Что мы выиграем, используя COW в этом примере?
Если все, что мы собираемся сделать, это использовать константные операции, s1
это избыточно, может также использоваться s
.
Если мы намереваемся изменить значение, то COW только задерживает копирование ресурса до первой неконстантной операции, за счет (хотя и минимальной) стоимости увеличения числа ссылок для неявного совместного использования и отключения от общего хранилища. Похоже, что все накладные расходы, связанные с COW, бессмысленны.
Он не сильно отличается в контексте передачи параметров - если вы не собираетесь изменять значение, передайте как константную ссылку, если вы хотите изменить, вы либо создаете неявную глубокую копию, если не хотите изменять исходный объект, или передайте по ссылке, если вы хотите изменить его. Опять же, COW кажется ненужными накладными расходами, которые ничего не достигают, а лишь добавляет ограничение, что вы не можете изменять исходное значение, даже если хотите, так как любое изменение отсоединит от исходного объекта.
Таким образом, в зависимости от того, знаете ли вы о COW или не обращаете на это внимания, это может привести либо к коду с неясными намерениями и ненужными накладными расходами, либо к полностью запутывающему поведению, которое не соответствует ожиданиям и заставляет вас ломать голову.
Мне кажется, что есть более эффективные и более удобочитаемые решения, хотите ли вы избежать ненужной глубокой копии или намереваетесь ее сделать. Так где же практическая выгода от COW? Я предполагаю, что должна быть некоторая выгода, поскольку в ней используются такие популярные и мощные рамки.
Кроме того, из того, что я прочитал, COW теперь явно запрещено в стандартной библиотеке C ++. Не знаю, имеет ли отношение к этому мошенничество какое-то отношение, но в любом случае, для этого должна быть причина.
[]
оператор. Таким образом, COW допускает плохой дизайн - это не кажется большой выгодой :) Пункт в последнем параграфе кажется верным, но я сам не большой поклонник неявного поведения - люди склонны принимать это как должное, а затем трудно понять, почему код работает не так, как ожидалось, и все время удивляться, пока они не выяснят, что скрывается за скрытым поведением.