2012-02-28 2 views
3

Мне нужно защитить доступ к структуре данных в моем классе. Поскольку я не могу иметь мьютекс (потому что я не могу его скопировать), я рассматриваю возможность использования shared_ptr и сохранения мьютекса. Вот пример кода моей идеи:boost :: shared_ptr boost :: mutex и copy constructor

class Sample { 
    typedef boost::lock_guard<boost::mutex> AcquireLock; 
    boost::shared_ptr<boost::mutex> mutt; 

public: 
    Sample() : mutt(new boost::mutex) {} 

    void Method() 
    { 
     AcquireLock lock(*mutt); 

     //do some work here 
    } 
}; 

У меня есть следующие вопросы:

  • Является ли это плохая практика, чтобы использовать мьютекс таким образом (как член класса, через shared_ptr)?
  • Должен ли я иметь конструктор копирования для этого класса, так как он имеет память, выделенную в куче через shared_ptr?

EDIT: Возможно, мне нужно дать немного больше деталей: Я создам этот объект только один раз и сохраню его в std :: vector. Мне не нужно делать копии, и если вектор должен делать копии, я не хочу иметь разные мьютексы для каждой копии. Вот почему я думаю, что конструктор копирования будет работать для меня.

ответ

1

Если вы создадите экземпляр объекта Sample, будет вызываться конструктор копирования, который генерируется автоматически компилятором, или тот, который вы написали явно.

Независимо от того, можно ли разрешить копирование объектов Sample, зависит от того, что вы пытаетесь сделать. Если у вас нет смысла разрешать копии, сделайте объект не скопированным, например. предоставив частный прототип для конструктора копирования.

Если вы хотите разрешить копирование, вам необходимо решить, должен ли каждый экземпляр иметь свой собственный мьютекс и соответствующим образом определить конструктор копии. Созданный автоматически создатель копии будет делать только мелкую копию, поэтому все копии будут передавать мьютекс.

+0

У меня будут копии, потому что я сохраню объект в std :: vector и использую его оттуда. Кроме того, я не буду делать никаких копий, поэтому я думаю, что для меня будет работать конструктор экземпляров по умолчанию. Мне интересно, если мелкая копия испортит счетчик ссылок или что-то подобное, что вызовет проблемы в будущем. –

+1

Почему бы не сохранить shared_ptr объекта Sample в векторе, тогда вам не нужно беспокоиться о копировании объекта Sample –

2

Этот подход довольно действителен и закончен, но обратите внимание, что по мере развития вашего класса вы можете применить ту же технику к некоторым другим членам класса. Вот почему я бы рекомендовал вам рассмотреть возможность использования pImpl idiom:

// in hpp: 
class Sample 
{ 
    Impl(); 
private: 
    struct Impl; 
    // compiler generated copy-constructor will copy only this shared_ptr 
    shared_ptr<void> pImpl_; 
}; 

// in cpp: 
struct Sample::Impl 
{ 
    mutex mut_; 
    // put here whatever members you need, extend Impl without affecting the Sample interface 
}; 

Impl::Impl() : pImpl_(new Impl) 
{} 
Смежные вопросы