У меня есть существующая переменная, например.
int a = 3;
Как мне теперь создать от boost::shared_ptr
до a
? Например:
boost::shared_ptr< int > a_ptr = &a; // this doesn't work
У меня есть существующая переменная, например.
int a = 3;
Как мне теперь создать от boost::shared_ptr
до a
? Например:
boost::shared_ptr< int > a_ptr = &a; // this doesn't work
хотя вы должны поместить переменную в управляемый указатель при ее создании, чтобы сделать это из существующего указателя.
int *a=new int;
boost::shared_ptr<int> a_ptr(a);
Если по какой-то причине функция принимает shared_ptr, а у вас есть только переменная стека, вам лучше сделать это:
int a=9;
boost::shared_ptr<int> a_ptr=boost::make_shared(a);
Глянь сюда:
http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/make_shared.html
также стоит отметить, что shared_ptr находится в стандарте С++ 11, если вы можете его использовать. Вы можете использовать auto в сочетании с make_shared, как заметки Херба Саттера в разговоре о сборке.
#include <memory>
int a=9;
auto a_ptr=std::make_shared(9);
Во-первых, у вас есть ошибка, потому что 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
фактически не удалял то, на что указывает:Плюсы:
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);
То, что вы написали, не будет работать, потому что конструктор shared_ptr
, который вы ищете, - это explicit
, поэтому вам нужно написать его так
boost::shared_ptr<int> a_ptr(&a); // Don't do that!
Однако проблема с этим заключается в том, что delete
будет вызываться для сохраненного значения a_ptr
. Поскольку в вашем примере a
имеет автоматическую продолжительность хранения, это очень плохо. Таким образом, мы также передаем пользовательский модуль удаления:
boost::shared_ptr<int> a_ptr(&a, noop_deleter);
Реализация noop_deleter
для С++ 11:
auto noop_deleter = [](int*) {};
Версия С++ 03:
// Can't be put in local scope
struct {
void
operator()(int*) const
{}
} noop_deleter;
make_shared
легче справиться, но я действительно думаю, что это лучший ответ.
- person Omnifarious; 11.12.2011
noop_deleter
шаблоном.
- person Yakov Galka; 11.12.2011
shared_ptr
не исчезнет раньше, чем переменная стека. Но это НАМНОГО эффективнее, чем создание копии в куче. И ybungalobill прав, это единственный технически правильный ответ на поставленный вопрос. Это не заслужило отрицательного голоса.
- person Omnifarious; 11.12.2011
noop_deleter
здесь не имя типа, а объект этого (анонимного) типа.
- person Luc Danton; 03.12.2012
Вы не можете создать boost::shared_ptr для существующей переменной. Элементы, хранящиеся в boost::shared_ptr, сохраняются при создании.
Однако вы можете создать boost::shared_ptr, который будет копией существующей переменной.
Например
int a = 3; // Existing variable
boost::shared_ptr<int> aCopy = boost::make_shared<int>(a); //Create copy with value of a
Обратите внимание, что вам нужно будет включить <boost/make_shared.hpp>
для make_shared.
shared_ptr
! - person curiousguy   schedule 16.12.2011