Во-первых, у вас есть ошибка, потому что shared_ptr
не будет автоматически преобразовываться из указателя соответствующего типа.Вы должны четко указать, что вы хотите сделать:
int a = 3;
::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!
У вас есть другая проблема.Представьте себе эффект этого кода:
int a = 3;
delete &a;
В первом примере, который я привел, это неизбежно произойдет, даже если это не совсем так прямо.shared_ptr
вся причина существования заключается в удалении вещей, когда все указатели на него исчезают.Это, конечно, вызовет все виды странного поведения.
У вас есть два способа решения этой проблемы.Одним из них является создание чего-то, что можно удалить.Другой - убедиться, что shared_ptr
на самом деле не удаляет то, на что он указывает.У каждого есть свои плюсы и минусы.
Создание чего-то, что можно удалить:
Плюсы:
- Просто и легко.
- Вы надеваетеНе нужно беспокоиться о времени жизни объекта.
Минусы:
- Немного на медленной стороне, поскольку это потребует выделения кучи или двух.
- Полученный
shared_ptr
будет ссылаться на копию, поэтому изменения в a
не будут отражены в значении того, на что он указывает.
Как это сделать:
::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));
Это довольно похоже на (и это также будет работать):
::boost::shared_ptr<int> a_ptr(new int(a));
Но это немного более эффективно.::boost::make_shared
делает некоторую магию, чтобы распределить счетчик ссылок и объект в непрерывной памяти, что экономит на вызовах распределителю и улучшает локальность ссылок.
Делая так, чтобы shared_ptr
фактически не удалял то, что онуказывает на:
Плюсы:
- Быстрее, хотя это все еще включает выделение кучи для счетчика ссылок
- Непосредственно решает проблему под рукой (вещь, которую вы 'повторное указание не может быть удалено).
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * при его использовалось бы указывать
a
.* Минусы:
- Требуется знать немного больше о том, как работает
shared_ptr
, а это значит, что люди, читающие ваш код, тоже должны знать. - Если выповторное указание выходит из области видимости раньше, чем все
shared_ptr
, которые указывают на это, затем эти указатели становятся висящими, и это плохо. - Предыдущий пункт делает это очень рискованным решением .Я бы вообще этого избегал.
Как это сделать:
Где-то за пределами функции (возможно, в анонимном пространстве имен):
void do_nothing_deleter(int *)
{
return;
}
А потом вфункция:
int a = 3;
::boost::shared_ptr a_ptr(&a, do_nothing_deleter);