Я просто видел эту хорошую реализацию указателя копии на записи. Это выглядит довольно универсальным и полезным, таким образом, мой вопрос: такой класс содержится в каком-либо из инструментариев C++ (повышение, loki, и т.д.)? В противном случае я действительно хотел бы знать, почему, потому что это - действительно полезная идиома и по-видимому универсальная реализация кажется выполнимой (как тот, который я связал с).
Как сказал Джерри Коффин, было продемонстрировано, что идиома COW вызывает проблемы с производительностью ... но на самом деле есть еще одна проблема.
Невозможно (как показано в той самой статье, на которую вы ссылаетесь) на самом деле написать общую реализацию COW. В реализации COW std :: string
Копирование выполняется всякий раз, когда вызывается операция, которая фактически изменяет состояние строки. Однако откуда указателю это знать? Он ничего не знает о классе, на который указывает.
Например, предположим, что я делаю это:
void method(Foo& foo, flag_t flag)
{
if (flag == flag::Yes) foo.modify();
}
void invoke(COWPointer<Foo> ptr)
{
method(*ptr, flag::No);
}
Упс! Я делаю копию объекта Foo
, даже если он не будет изменяться!
Проблема в том, что, хотя этот класс COW помогает, вам нужно его обернуть:
class Foo
{
public:
private:
COWPointer<FooImpl> mImpl;
};
И тогда методы Foo, которые действительно изменяют объект, будут отвечать за копирование состояния FooImpl
. Конечно, этот класс помогает, но это тоже не серебряная пуля.
И все эти проблемы ... не будучи уверенным в том, что реально повысить производительность из-за проблем с синхронизацией в приложении MT ...
Разве не проще на самом деле избегать копирования, когда это возможно (используя ссылки / указатели), чем настройка вашего класса для возможного выигрыша в некоторых ситуациях, которые будут наказывать пользователей, которые уже позаботились о проблемах с производительностью?
По поводу этой возможности было много споров, и по крайней мере одна предложенная версия того, что в конечном итоге вышло как auto_ptr
, предназначалась для указатель COW с подсчетом ссылок.
К сожалению, время для COW в основном прошло. Обеспечение потокобезопасности указателя COW (или чего угодно COW) может вызвать серьезные проблемы с производительностью .
Править: Перечитывая это, я чувствую себя обязанным отметить, что не все использование COW обязательно устарело. Иногда это все еще имеет смысл. Накладные расходы на потокобезопасное приращение в значительной степени исправлены - поэтому вопрос только в том, насколько большим должен быть объект или насколько дорого стоит копирование, чтобы COW имела смысл. Также есть моменты / места, когда у вас есть лоты копий (немодифицированного) объекта, и экономия памяти может быть разумным компромиссом - экономия памяти оправдывает некоторое дополнительное время процессора. Если вы можете сохранить подкачку небольших данных на / с диска, вы можете быстро выйти вперед.