开发者

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

开发者 https://www.devze.com 2022-12-24 09:42 出处:网络
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 thewrapped pointer, and just uses it to invoke

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


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消