Reputation: 27385
I'm reading Scott Meyrses' C++ and come across the following code:
class Lock {
public:
explicit Lock(Mutex *pm) // init shared_ptr with the Mutex
: mutexPtr(pm, unlock) // to point to and the unlock func
{
lock(mutexPtr.get()); // see Item15 for info on “get”
}
private:
std::tr1::shared_ptr<Mutex> mutexPtr; // use shared_ptr
}; // instead of raw pointer
In a footnote, he said that the code is not exception-safe. So in his blog he proposed to modify the constructor of the calss as follows:
explicit Lock(Mutex *pm)
{
lock(pm);
mutexPtr.reset(pm, unlock);
}
That's not clear why this code should work. We call the reset method on the not yet initialized mutextPtr
(we removed the entry from the ctor-initializer). Why won't we get something lie Segmenetation fault
?
Upvotes: 0
Views: 100
Reputation: 103713
mutexPtr
is not uninitialized. When you leave something out of the initializer list, its default constructor is called, if it has one. shared_ptr
has a default constructor, which sets the held pointer to null (i.e. no object is managed). The call to reset
then sets it to manage pm
. Nothing is deleted, because nothing was held. Even if delete
was called on the held pointer, delete
on a null pointer is a no-op, so it's not a problem.
Upvotes: 1