2016-05-11 8 views
2
class A 
{ 
private: 
    class B 
    { 
    private: 
     std::mutex mu; 
     A* parent = NULL; 
    public: 
     B(A* const parent_ptr): parent(parent_ptr) {} 
     B(const A::B & b_copy) { /* I thought I needed code here */ } 
    }; 
public: 
    B b = B(this); //...to make this copy instruction work. 
        // (Copy constructor is deleted, need to declare a new one?) 
}; 

У меня есть класс B, который в основном представляет собой поточную очередь задач. Он содержит deque, a mutex и condition_variable. Это облегчает отношения между потребителями и производителями между любыми двумя потоками, которые запускаются классом A. Я упростил код как можно больше.Копировать или перемещать конструктор для класса с элементом std :: mutex (или другим не скопированным объектом)?

Проблема начинается с наличия mutex в качестве члена: это удаляет конструктор копии по умолчанию. Это просто означает, что я могу построить с помощью B(this), но я не могу построить и, используя B b = B(this), что и нужно сделать в последней строке, чтобы дать классу A членам класса B. Каков наилучший способ решить эту проблему?

ответ

3

Простое решение заключается в использовании std::unique_ptr<std::mutex> в своем классе, и инициализировать его с std::make_unique(...) где ... ваши std::mutex аргументы конструктора, если таковые имеются.

Это позволит перемещать, но не копировать. Чтобы сделать его доступным для копирования, вам нужно будет инициализировать копию в конструкторе копирования, предполагая, что копии должны иметь свою собственную блокировку.

Если копии должны использовать этот замок, тогда вы должны использовать std::shared_ptr. Это можно копировать и перемещать.

1

Благодаря предложению Дуга по использованию std :: unique_ptr, мой класс довольно просто сейчас и делает то, что я хочу. Вот мое окончательное решение.

class A 
{ 
private: 
    class B 
    { 
    private: 
     std::unique_ptr<std::mutex> mu_ptr = std::make_unique<std::mutex>() 
     A* parent = NULL; 
    public: 
     B(A* const parent_ptr) : parent(parent_ptr) {} 
    }; 
public: 
    B b = B(this); // This now works! Great. 
};