Здравствуйте, MarcoPolo, Вы писали:
MP>Как я вижу, такая конструкция не особо используется.
MP>В чем причина?
Вроде бы сама строка внутри реф. каунт (реализация, но информация не совсем точна).
Хотя обычно строки лучше делать иммутабельными — как во многих языках программирования — чтобы не было вау-эффекта (эффекта неожиданности от изменения шареных строк).
Третий Рим должен пасть!
Re: std::shared_ptr<std::string> - имеет ли смысл?
Здравствуйте, MarcoPolo, Вы писали:
MP>Как я понимаю, если использовать эту конструкцию, за хранение каждой строки будет оверхед в виде reference counter в shared_ptr.
Главный оверхед будет в обязательном динамическом выделении памяти в размере sizeof(std::string) + размер счетчика.
Короткие строки могут вообще обходится без аллокаций, используя внутренний буфер (Short String Optimization).
Для длинных строк получится 2 аллокации при использовании std::make_shared и 3 — без нее (счетчик, сам std::string, буфер char'ов внутри std::string).
MP>Зато не будет вызовов конструкторов копирования std::string, и упрощается ownership таких объектов.
Начиная с С++ 11 избегать избыточного копирования (например, при заполнении контейнеров) можно с помощью move конструкторов и присваивания.
Раньше тоже можно было через swap, но менее удобно.
Плюс копирование std::shared_ptr<> использует атомарные операции над счетчиком.
По поводу ownership.
Использование std::shared_ptr<std::string> может преподнести массу сюрпризов, т.к. это даже не "копирование при записи" (Copy-On-Write).
Любое изменение будут видеть все владельцы, что обычно не есть гуд.
Можно бороться с этим путем раздачи константных строк std::shared_ptr<const std::string>, как уже посоветовали в соседнем ответе.
Но, в целом, для таких мелких и многочисленных объектов как строки подсчет ссылок считается антипаттерном.
Re[2]: std::shared_ptr<std::string> - имеет ли смысл?
Здравствуйте, GhostCoders, Вы писали:
GC>Здравствуйте, MarcoPolo, Вы писали:
MP>>Как я вижу, такая конструкция не особо используется.
MP>>В чем причина? GC>Вроде бы сама строка внутри реф. каунт (реализация, но информация не совсем точна).
Нет. (В подавляющем большенстве современных реализаций.)
Потому что идея COW (copy on write) приводит к слишком частому копированию строки.
При вызове любого метода доступа к символу (operator[], at, c_str, begin, end, ...), применительно к не-константному экземпляру строки, придется считать эту операцию всегда доступокм для модификации элемента, даже если на самом деле, это чтение. При копировании строки, к которой ранее, хоть раз, обращались через operator[] все равно, предется копировать содрежимое строки, потому что ссылка на char могла где-то сохраниться и потом будет использована для модификации строки.
Есть BSTR из COM, со счетчиком. Но там другой интерфейс, из которого очевидно, что мы модифицируем общую строку.
GC>Хотя обычно строки лучше делать иммутабельными — как во многих языках программирования — чтобы не было вау-эффекта (эффекта неожиданности от изменения шареных строк).
Иммутабельная версия строки называется std::string_view, или const std::string& (в совсем старых стандартах).
Re: std::shared_ptr<std::string> - имеет ли смысл?
Здравствуйте, MarcoPolo, Вы писали:
MP>Зато не будет вызовов конструкторов копирования std::string, и упрощается ownership таких объектов.
чтобы не было копирования есть константные ссылки, перемещение и string_view. И в чём упрощение ownership, т.е. с чего вдруг шареный ownership проще single ownership?
MP>Как я вижу, такая конструкция не особо используется.
потому что смысл этой конструкции не в экономии тактов, а в особой (shared) семантике владения, которая, очевидно, нужна не так часто.
нормально делай — нормально будет
Re: std::shared_ptr<std::string> - имеет ли смысл?
Здравствуйте, MarcoPolo, Вы писали: MP>Есть ли смысл использовать std::shared_ptr<std::string> вместо std::string, для представления строковых объектов в проекте?
Нет. MP>Как я понимаю, если использовать эту конструкцию, за хранение каждой строки будет оверхед в виде reference counter в shared_ptr.
И вызов блокировки мьютекса при обращении. MP>Зато не будет вызовов конструкторов копирования std::string, и упрощается ownership таких объектов.
Я так понимаю, ты решаешь проблему не тем путём. Чтобы избегать избыточного копирования необходимо понять что такое копирующий конструктор, конструктор перемещение, move-семантика, RVO и NRVO, когда и что из этого работает. Потом почитать rvalues, lvalues, xvalues, glvalues, и prvalues.
Скрытый текст
Потом удалить С++ с пека навсегда, торжественно сжечь книгу Страуструпа, Стандарт и перейти на что-то другое
MP>Как я вижу, такая конструкция не особо используется.
Она не нужна если у тебя нет какого-то сложноного управления владением или временем жизни этой строки в многопоточном коде. MP>В чем причина?
Почти бесполезная штука.
Здравствуйте, MarcoPolo, Вы писали:
MP>Есть ли смысл использовать std::shared_ptr<std::string> вместо std::string, для представления строковых объектов в проекте?
Нет, нет смысла.
Тем более, что в основном объекты типа std::string — локальные (на стеке) и здесь забота об освобождении памяти не нужна.
MP>Как я понимаю, если использовать эту конструкцию, за хранение каждой строки будет оверхед в виде reference counter в shared_ptr.
Как минимум в виде "reference_counter".
MP>Зато не будет вызовов конструкторов копирования std::string, и упрощается ownership таких объектов.
Зато будут "посторонние данные" которые по месту применения не нужны.
Хуже того, мы (изменяя эти строки) — сможем повредить строковые данные в совершенно неожиданных местах.
MP>Как я вижу, такая конструкция не особо используется.
Нет смысла в использовании.