I have an existing variable, e.g.
int a = 3;
How can I now create a boost::shared_ptr
to a
? For example:
although you should put the variable into a managed pointer on it's creation to do it from an existing pointer.
int *a=new int;
boost::shared_ptr<int> a_ptr(a);
If for some reason a function takes shared_ptr and you only have a stack varaible you are better off doing this:
int a=9;
boost::shared_ptr<int> a_ptr=boost::make_shared(a);
See here:
http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/make_shared.html
also it is worth noting that shared_ptr is in the c++11 standard if you are able using that. You can use auto in combination with make_shared like Herb Sutter notes in the build talk.
#include <memory>
int a=9;
auto a_ptr=std::make_shared(9);
First, you have an error because shared_ptr
's will not automatically convert from a pointer of the appropriate type. You have to explicitly state that's what you want to do:
int a = 3;
::boost::shared_ptr< int > a_ptr(&a); // DO NOT DO THIS!
You have another problem though. Imagine the effect of this code:
int a = 3;
delete &a;
In the first example I gave, this will inevitably happen, even if it's not quite so direct. shared_ptr
's whole reason for existence is deleting things when all the pointers to it go away. This, of course, will cause all manner of strange behavior.
You have two ways of dealing with this issue. One is to create something that can be deleted. The other is to make sure that shared_ptr
doesn't actually delete the thing it points to. There are pros and cons to each.
Pros:
Cons:
shared_ptr
will refer to a copy, so modifications to a
will not be reflected in the value of the thing it points to.How to do it:
::boost::shared_ptr<int> a_ptr(::boost::make_shared(a));
This is rather similar to (and this will also work):
::boost::shared_ptr<int> a_ptr(new int(a));
But it's slightly more efficient. ::boost::make_shared
does some magic to allocate the reference count and the object in contiguous memory which saves on calls to the allocator and improves locality of reference.
shared_ptr
doesn't actually delete what it points to:Pros:
shared_ptr
refers to a
, so if you change its value things that access it through the pointer will see the new value.Cons:
shared_ptr
works, which means the people reading your code have to know too.shared_ptr
's that point to it do, then those pointers become dangling, and that's bad.How to do it:
Somewhere outside the function (probably in an anonymous namespace):
void do_nothing_deleter(int *)
{
return;
}
And then in the function:
int a = 3;
::boost::shared_ptr a_ptr(&a, do_nothing_deleter);
What you wrote won't work because the constructor of shared_ptr
you're looking for is explicit
, so you'd need to write it like so
boost::shared_ptr<int> a_ptr(&a); // Don't do that!
The problem with that however, is that delete
will be called on the stored value of a_ptr
. Since in your example a
has automatic storage duration, this is very bad. So we pass in a custom deleter too:
boost::shared_ptr<int> a_ptr(&a, noop_deleter);
An implementation of noop_deleter
for C++11:
auto noop_deleter = [](int*) {};
C++03 version:
// Can't be put in local scope
struct {
void
operator()(int*) const
{}
} noop_deleter;
You cannot create a boost::shared_ptr for an existing variable. Items stored in a boost::shared_ptr are stored at creation.
You can however make a boost::shared_ptr that is a copy of an existing variable.
For example
int a = 3; // Existing variable
boost::shared_ptr<int> aCopy = boost::make_shared<int>(a); //Create copy with value of a
Note that you will need to include <boost/make_shared.hpp>
for make_shared.