Как сказал Джерри Коффин, было продемонстрировано, что идиома 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);
}
Oups! Я делаю копию объекта Foo
, даже если он не будет изменен!
Проблема в том, что хотя этот класс COW помогает, на самом деле его нужно обернуть:
class Foo
{
public:
private:
COWPointer<FooImpl> mImpl;
};
И тогда методы Foo, которые действительно изменяют объект, будут отвечать за копирование состояния FooImpl
. Поэтому уверен, что класс помогает, но это не серебряная пуля.
И все эти проблемы ... не будучи уверенными в том, что на самом деле набирают производительность из-за проблем с синхронизацией в приложении MT ...
Не проще ли на самом деле избегать копирования, когда это возможно (используя ссылки / указатели), вместо того, чтобы настраивать свой класс на возможный выигрыш в некоторых ситуациях, которые будут наказывать пользователей, которые уже позаботились о проблемах производительности?