I was reading an article and I found a small example to demonstrate the use of boost::scoped_ptr
:
#include
#include
#include
#include
static int count = 0;
class printer
{
int m_id;
public:
printer(void) :
m_id(count++)
{
}
~printer(void)
{
std::cout << "Printer " << m_id
<< " destroyed" << std::endl;
}
};
int
main(void)
{
boost::scoped_ptr p1(new printer);
boost::scoped_ptr p2(new printer);
std::cout << "Exiting test program" << std::endl;
return EXIT_SUCCESS;
}
The only thing I didnt understand in the article was this statement:
using
scoped_ptr
, you indicate that ownership transfer is not intended or allowed.
Maybe it was the wrong article to begin with as a beginner on this topic, but what exactly the above line means?
Answer
Most smart pointers have ownership of the object they are pointing to - they are in charge of destroying that object when the time comes. However, different smart pointers have different ownership semantics. That is, they tell the user of that smart pointer how the ownership may or may not be transferred, how it is shared amongst objects, when the object should be deleted, and so on. Using a certain smart pointer describes your intent with regards to the ownership of that object. Ownership can be transferred to other functions or objects.
boost::scoped_ptr
has very strict ownership semantics. It doesn't allow any transfer of ownership at all. It achieves this by being non-copyable (so you can't pass it to another function by value).
As another example, a std::unique_ptr
is also fairly strict. Its special ability is that it can be moved from. Passing an std::unique_ptr
to a function as an rvalue will let that function steal ownership of the object. The original std::unique_ptr
loses that ownership immediately. This ensures that ownership is only ever held by one std::unique_ptr
.
The equivalent to boost::scoped_ptr
in C++11 is a const std::unique_ptr
. This is because making it const
prevents any moving and thus ownership can not be transferred.
An easy way to see how important ownership semantics are is with an example. Let's say you're using an evil developer's library and it has a function that you don't know the implementation of, such as:
cat* foo();
You know this function returns a pointer to a cat
. However, it's a raw pointer. You have no idea whether you should be destroying the cat (with delete
) at some point or if the library will do it for you. You don't even know if the object was actually dynamically allocated. You have no idea if the library still keeps hold of the cat
. In the past, if you had a function like this, you would need to look up the documentation to find out what to do. However, now that we have smart pointers in addition to raw pointers, raw pointers have their own ownership semantics - the most relaxed of them all. It says "You better trust me that I keep this cat
valid for as long as you pass it around but I'll be the one managing it. Don't keep it for too long."
However, a wise and kind library developer would now write this function like so:
std::unique_ptr foo();
So how does this help? Well, the std::unique_ptr
tells you a lot. It tells you that the function is giving up ownership of the cat
object to you. The cat
is now your sole responsibility. It's also very helpful in giving you a smart pointer because you don't need to think about delete
ing it. You can just use the pointer and when it goes out of scope, the object will be destroyed. Or, if you want to, you can transfer ownership to another function.
This doesn't mean that only one pointer will ever have ownership of the cat
though. As the proud new owner, it's up to you to decide what happens next. It's perfectly reasonable for you to decide that you want to start sharing ownership of your cat
:
std::unique_ptr up = foo();
std::shared_ptr sp(up.release());
The wise and kind foo
library developer only told you what her intentions were. She gave you the cat
and now you're the owner. Now you can provide your own ownership semantics.
In this way, a boost::scoped_ptr
is a bit like a greedy cat
hoarder who will never share the cat
with anybody, never give the cat to anybody, and will keep it until the day they die.
No comments:
Post a Comment