St.Antario
St.Antario

Reputation: 27385

RAII objects tr1:shared_ptr

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

Answers (1)

Benjamin Lindley
Benjamin Lindley

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

Related Questions