2015-07-17 6 views
0

Я читаю Скотта Meyrses' C++ и наткнулся на следующий код:RAII объектов tr1: shared_ptr

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 

В сноске, он сказал, что код не является исключением безопасной. Таким образом, в his blog он предложил изменить конструктор Calss следующим образом:

explicit Lock(Mutex *pm) 
{ 
    lock(pm); 
    mutexPtr.reset(pm, unlock); 
} 

Это не понятно, почему этот код должен работать. Мы называем метод сброса еще не инициализированным mutextPtr (мы удалили запись из ctor-initializer). Почему мы не получим что-то ложное Segmenetation fault?

+0

'std :: tr1' устарел, как и книга. Я бы порекомендовал вам перейти на [Эффективный современный C++] (http://www.amazon.com/Effective-Modern-Specific-Ways-Improve/dp/1491903996), если вы довольны стилем Скотта Мейерса или чем-то вроде [здесь] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – nwp

ответ

1

mutexPtr не является неинициализированным. Когда вы оставляете что-то из списка инициализаторов, вызывается его конструктор по умолчанию, если он есть. shared_ptr имеет конструктор по умолчанию, который устанавливает удерживаемый указатель в нуль (т. Е. Никакой объект не управляется). Затем вызов reset устанавливает управление pm. Ничего не удалено, потому что ничего не было. Даже если на удерживаемый указатель был вызван delete, delete на нулевом указателе - нет-op, поэтому это не проблема.

 Смежные вопросы

  • Нет связанных вопросов^_^