Во-первых, какова типичная реализация std::weak_ptr
? Особенно это std::weak_ptr
просто указатель на блок управления std::shared_ptr
?
Если все std::shared_ptr
ссылки ушли, блок внутреннего контроля удален? Если да, то как std::weak_ptr::expired()
функционировать правильно, если эта память переопределена?
У меня есть объект, который содержит std::weak_ptr
, и я хочу memcpy
объект в буфер для последующей обработки. Это каким-то образом нарушит внутреннюю работу умного указателя?
Когда все std::shared_ptr
объекты исчезли, блок управления все еще существует (вот как std::weak_ptr
работы), только указанный объект удаляется.
Теперь объект C ++ можно безопасно скопировать с помощью std::memcpy
только если это тривиально копируемый. Проверка требований TriviallyCopyable
концепция, мы видим, что std::weak_ptr
не удовлетворяет его из-за наличия нетривиального конструктора копирования. Фактически, этот конструктор будет увеличивать счетчик слабых указателей внутри блока управления, поэтому копируем его std::memcpy
сломал бы его инварианты.
Если честно, храню std::weak_ptr
в сыром буфере звучит как ужасная идея в обычном коде. Буферы обычно используются для сериализации, отправки / записи данных и т. Д., И все эти задачи бессмысленны для интеллектуального указателя. Однако, если вы абсолютно уверены, что вам нужно сохранить его в буфере, вам нужно размещение new
:
std::weak_ptr<T> the_one_i_want_to_copy;
std::weak_ptr<T> * buffer = ...;
new (buffer) std::weak_ptr<T> { the_one_i_want_to_copy };
Обратите внимание на (buffer)
после new
: оно говорит new
не выделять память, а использовать уже подготовленное место (таким образом, местоновый). При подготовке buffer
, обязательно укажите необходимый размер и выравнивание.
Других решений пока нет …