I have few questions on the best practices of using shared_ptr
.
Question 1
Is copying shared_ptr
cheap? Or do I need to pass it as reference to my own helper functions and return as value? Something like,
void init_fields(boost::shared_ptr<foo>& /*p_foo*/);
void init_other_fields(boost::shared_ptr<foo>& /*p_foo*/);
boost::shared_ptr<foo> create_foo()
{
boost::shared_ptr<foo> p_foo(new foo);
init_fields(p_foo);
init_other_fields(p_foo);
}
Question 2
Should I use boost::make_shared
to construct a shared_ptr
? If yes, what advantages it offers? And how can we use make_shared
when T
doesn't have a parameter-less constructor?
Question 3
How to use const foo*
? I have found two approaches for doing this.
void take_const_foo(const foo* pfoo)
{
}
int main()
{
boost::shared_ptr<foo> pfoo(new foo);
take_const_foo(pfoo.get());
return 0;
}
OR
typedef boost::shared_ptr<foo> p_foo;
typedef const boost::shared_ptr<const foo> const_p_foo;
void take_const_foo(const_p_foo pfoo)
{
}
int main()
{
boost::shared_ptr<foo> pfoo(new foo);
take_const_foo(pfoo);
return 0;
}
Question 4
How can I return and check for NULL
on a shared_ptr
object? Is it something like,
boost::shared_ptr<foo> get_foo()
{
boost::shared_ptr<foo> null_foo;
return null_foo;
}
int main()
{
boost::shared_ptr<foo> f = get_foo();
if(f == NULL)
{
/* .. */
}
return 0;
}
Any help would be great.
So, we should use shared_ptr when we want to assign one raw pointer to multiple owners. // referring to the same managed object. When to use shared_ptr? Use shared_ptr if you want to share ownership of a resource.
The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.
Use unique_ptr when if you want to have single ownership(Exclusive) of resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. Use shared_ptr if you want to share ownership of resource .
Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.
Most of the questions have been answered, but I disagree that a shared_ptr copy is cheap.
A copy has different semantics from a pass-by-reference. It will modify the reference count, which will trigger an atomic increment in the best case and a lock in the worst case. You must decide what semantics you need and then you will know whether to pass by reference or by value.
From a performance point of view, it's usually a better idea to use a boost pointer container instead of a container of shared_ptr.
Copying is cheap, the pointer doesn't take much space. The whole point of it was to make it small to allow usage in containers by value ( e.g. std::vector< shared_ptr<Foo> >
).
make_shared
takes a variable amount of parameters, and is the prefered mechanicsm over constructing it yourself (just like make_pair
). The advantage is readability, especially if passing temporaries and/or namespaces is involved:
boost::const_ptr_cast as already suggested
smart pointers have overloaded operators and may be directly used in expressions evaluated to bool. Don't use get
. For anything. Instead of comparing p.get
to anything, compare a empty pointer instance ( my_ptr != boost::shared_ptr< MyClass >()
)
AD.2
func_shared( boost::shared_ptr<my_tools::MyLongNamedClass>(
new my_tools::MyLongNamedClass( param1, param2 ) );
versus
func_shared( boost::make_shared<my_tools::MyLongNamedClass>( param1, param2 ));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With