Возможно ли, что на C++ 11 иметь объект, управляемый несколькими std::shared_ptr
s. Я хочу удалить объект через один std::shared_ptr
, а другой shared_ptr
s недействителен (установлен пустой или пустой), возможно ли это? Если нет, то какой лучший способ информировать все другие «ссылки» (при либеральном использовании слова) о том, что объект больше недействителен?Недействить все общие ptrs к определенному управляемому объекту
ответ
Для этого необходимо заменить shared_ptr
s на weak_ptr
. shared_ptr
, который делает удаление, фактически управляет временем жизни объекта в этом сценарии. Стоит на этом этапе выяснить, действительно ли вам нужна семантика совместного использования. В общем, если вы пытаетесь что-то сделать, интерфейс не позволяет вам это делать, это указывает на то, что вам нужно что-то с другой семантикой.
В качестве альтернативы, если вы действительно не можете управлять жизненным циклом объекта с одного места, вы можете использовать shared_ptr<unique_ptr<T>>
, но это более громоздко (не говоря уже о более медленном), и его лучше избегать. Здесь вы должны удалить объект по reset
ting the inner unique_ptr
.
Here является хорошим примером weak_ptr
и должен быть информирован о том, что все другие ссылки ссылаются на более поздние сроки.
#include <iostream>
#include <memory>
std::weak_ptr<int> gw;
void f()
{
std::cout << "use_count == " << gw.use_count() << ": ";
if (auto spt = gw.lock())
{ // Has to be copied into a shared_ptr before usage
std::cout << *spt << "\n";
}
else
{
std::cout << "gw is expired\n";
}
}
int main()
{
{
std::shared_ptr<int> sp = std::make_shared<int>(42);
gw = sp;
f();
}
f();
}
Выход:
use_count == 1: 42
use_count == 0: дш истек
Вы всегда знаете, какой один конкретный 'shared_ptr' будет делать исключение? Или это может быть произвольным? – Angew
Да, я знаю, какой 'shared_ptr' выполнит удаление. – shane
Добавьте уровень косвенности. Имейте объект оболочки, содержащий реальный объект, и разделите указатели на обертку. Когда придет время, попросите обертку удалить реальный объект, после чего он начнет сообщать о какой-либо ошибке в своих аксессуарах (например, return 'nullptr' из своего' RealObject * getReal() ') –