Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it good practice to pass scoped_ptr by reference (from one method to another inside a class)?

Or if i need to do that, then i should just use shared_ptr?

like image 547
amitlicht Avatar asked Mar 21 '10 19:03

amitlicht


2 Answers

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 to boost::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.

like image 191
Nikolai Fetissov Avatar answered Nov 11 '22 20:11

Nikolai Fetissov


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).

like image 27
UncleBens Avatar answered Nov 11 '22 20:11

UncleBens