Реализация идиомы copy-on-write

263
25 ноября 2017, 10:46

В книге Скотта Майерса - "Наиболее эффективное использование C++" в правиле 29 приводится реализация группы классов для обслуживания пользовательского класса Widget посредством создания класса-обертки RCWidget, содержащего указатель RCIPtr<Widget> и перенаправляющие функции. Этот механизм соответствует современному std::shared_ptr за исключением того, что в механизме Майерса имеется возможность при изменении данных по указателю отделить его от остальных и создать копию данных, т.е. значение разделяется до тех пор, пока его изменят в одном из указателей - тогда создается дополнительная копия.

Вопрос в том, является ли эта реализация приемлемой на современном стандарте C++ и, если нет, то в чем ее следует дорабатывать? Есть реализация такого надстроечного механизма в boost или еще где-то?

P.S. Код не приложил, просто под рукой только книга и телефон, а он на 2.5 стр. Если у кого-нибудь есть электронная версия - дополните, пожалуйста.

Answer 1

Дать однозначный ответ нельзя.

С одной стороны, более распространённым является intrusive-подход, когда объект сам управляет разделением своих данных (и, соответственно, хранит в себе указатель на внутренний контейнер с ними). Это обосновывается инкапсуляцией и отсутствием лишних сущностей.

С другой же стороны, любой intrusive нарушает принцип «один класс — одна сущность», смешивая воедино основную функцию и диспетчер управления данными. К тому же, он обязывает программиста к постоянному использованию данного механизма, даже когда он избыточен.

Так что приемлемость того или иного подхода зависит от конкретной ситуации. Где-то применимы классы-обёртки, где-то — внутреннее управление силами самого объекта.

Answer 2

Это называется copy-on-write.

Примерно такого же можно добиться с std::shared_ptr<const T>.

При модификации объекта его надо явно копировать, например

auto s = make_shared<const string>("foo");
auto s2 = s;
auto s3 = make_shared<const string>(*s + "bar");
auto s4 = make_shared<string>(*s);
s4->resize(4);
shared_ptr<const string> s5 = s4;

Если на объект указывают только shared_ptr<const T>, то бонусом идет потокобезопасность - объект никогда не поменяется.

READ ALSO
Попадает ли точка в закрашенную область [требует правки]

Попадает ли точка в закрашенную область [требует правки]

Уважаемые, помогите пожалуйста! Мне нужно написать программу (мне хотя бы помощь) на С++Определить количество точек попадающих в фигуры 1 и 2 (радиус...

221
XOR шифрование типа double

XOR шифрование типа double

Здравствуйте, есть задание при помощи xor зашифровать и расшифровать массив double однобайтным ключомСложность возникла в том, как правильно...

249
Что за исключение: нарушение доступа для чтения _Pnext было 0xC?

Что за исключение: нарушение доступа для чтения _Pnext было 0xC?

Пишу программу выводящую на экран таблицу с данными учеников(ФИО, дата рождения, возраст)

603