std::shared_ptr<std::string> - имеет ли смысл?
От: MarcoPolo  
Дата: 14.02.20 05:57
Оценка:
Есть ли смысл использовать std::shared_ptr<std::string> вместо std::string, для представления строковых объектов в проекте?

Как я понимаю, если использовать эту конструкцию, за хранение каждой строки будет оверхед в виде reference counter в shared_ptr.

Зато не будет вызовов конструкторов копирования std::string, и упрощается ownership таких объектов.

Как я вижу, такая конструкция не особо используется.

В чем причина?
string c++ c++11
Re: std::shared_ptr<std::string> - имеет ли смысл?
От: GhostCoders Россия  
Дата: 14.02.20 06:02
Оценка:
Здравствуйте, MarcoPolo, Вы писали:

MP>Как я вижу, такая конструкция не особо используется.


MP>В чем причина?

Вроде бы сама строка внутри реф. каунт (реализация, но информация не совсем точна).
Хотя обычно строки лучше делать иммутабельными — как во многих языках программирования — чтобы не было вау-эффекта (эффекта неожиданности от изменения шареных строк).
Третий Рим должен пасть!
Re: std::shared_ptr<std::string> - имеет ли смысл?
От: qaz77  
Дата: 14.02.20 08:09
Оценка: +1
Здравствуйте, 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> - имеет ли смысл?
От: Chorkov Россия  
Дата: 14.02.20 08:34
Оценка: +1
Здравствуйте, 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> - имеет ли смысл?
От: Мирный герцог Ниоткуда  
Дата: 14.02.20 10:35
Оценка: +2
Здравствуйте, MarcoPolo, Вы писали:

MP>Зато не будет вызовов конструкторов копирования std::string, и упрощается ownership таких объектов.

чтобы не было копирования есть константные ссылки, перемещение и string_view. И в чём упрощение ownership, т.е. с чего вдруг шареный ownership проще single ownership?

MP>Как я вижу, такая конструкция не особо используется.

потому что смысл этой конструкции не в экономии тактов, а в особой (shared) семантике владения, которая, очевидно, нужна не так часто.
нормально делай — нормально будет
Re: std::shared_ptr<std::string> - имеет ли смысл?
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 14.02.20 13:21
Оценка:
Здравствуйте, 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>В чем причина?

Почти бесполезная штука.
Sic luceat lux!
Отредактировано 14.02.2020 13:23 Kernan . Предыдущая версия .
Re: std::shared_ptr<std::string> - имеет ли смысл?
От: AlexGin Беларусь  
Дата: 16.02.20 17:23
Оценка: -1
Здравствуйте, MarcoPolo, Вы писали:

MP>Есть ли смысл использовать std::shared_ptr<std::string> вместо std::string, для представления строковых объектов в проекте?

Нет, нет смысла.
Тем более, что в основном объекты типа std::string — локальные (на стеке) и здесь забота об освобождении памяти не нужна.

MP>Как я понимаю, если использовать эту конструкцию, за хранение каждой строки будет оверхед в виде reference counter в shared_ptr.

Как минимум в виде "reference_counter".

MP>Зато не будет вызовов конструкторов копирования std::string, и упрощается ownership таких объектов.

Зато будут "посторонние данные" которые по месту применения не нужны.
Хуже того, мы (изменяя эти строки) — сможем повредить строковые данные в совершенно неожиданных местах.

MP>Как я вижу, такая конструкция не особо используется.

Нет смысла в использовании.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.