Is it good practice to pass scoped_ptr by reference (from one method to another inside a class)?
Or if i nee开发者_JAVA百科d to do that, then i should just use shared_ptr?
It is safe to pass scoped_ptr
by reference if the callee doesn't need to store the wrapped pointer, and just uses it to invoke some methods. The object guarded by the scoped_ptr
will be destroyed when it goes out of scope - either at the end of the calling function if the pointer was a stack variable, or when the containing class instance is deallocated, if it was a member variable.
In general, smart pointers are there for managing object ownership, so here's a quick run down:
boost::scoped_ptr
restricts guarded object lifetime to the enclosing scope, there's only one owner.- With
std::auto_ptr
there's also only one owner at a time, but it allows passing the ownership via assignment (as function parameter or return value.) boost::shared_ptr
supports shared ownership via reference counting, the guarded object is only destroyed when reference count goes to zero. This is the most versatile smart pointer, but also the most expensive since it suffers some minor overhead (the reference count is maintained with atomic operations, which are rather expensive.) There's also possibility of circular dependencies.boost::weak_ptr
is a non-owning smart pointer, which could be upgraded toboost::shared_ptr
at runtime with a check that the guarded object is still alive.
There are also array variants like boost::shared_array
since C++ has separate deallocation functions for single and multiple objects (operator delete
vs. operator delete[]
.)
Smart pointers support the Resource Acquisition Is Initialization, or RAII, idiom, which is a way to provide exception safety guarantees.
Yes you can pass it by reference.
However, if the function just wants to use the managed object, you might consider passing a reference to the object itself.
void foo(const boost::scoped_ptr<Object>& o)
{
o->foobar();
}
void bar(const Object& o)
{
o.foobar();
}
The difference is that in the first case you have coupled the function with a particular smart pointer type.
Object o;
boost::scoped_ptr<Object> scoped(new Object);
boost::shared_ptr<Object> shared(new Object);
foo(o); //no
foo(scoped); //OK
foo(shared); //no
bar(o); //OK
bar(*scoped); //OK
bar(*shared); //OK
Generally I'd only pass the scoped_ptr
, if the intention is to do something with the scoped_ptr
instance itself (e.g release or reset the resource). Similarly for shared_ptr
(e.g the function wants to share the resource with other shared pointers).
Personally I pass shared_ptr by const reference almost everywhere. As others have said, if you're calling a function and passing a const reference, then the caller almost certainly is going to keep the shared_ptr in scope.
The real benefit is that you save the cost of updating the reference counter this way. A quick read of the wiki http://en.wikipedia.org/wiki/Reference_counting and you'll learn that constantly performing +1 / -1 (presumably atomic) operations on the reference counter can ravage your cache.
精彩评论