Скопировать или переместить конструктор для класса с членом std::mutex (или другим некопируемым объектом)?

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, mutex и condition_variable. Это облегчает отношения потребителя/производителя между любыми двумя потоками, запущенными классом A. Я максимально упростил код.

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


person OrangeSherbet    schedule 11.05.2016    source источник


Ответы (2)


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

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

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

person doug65536    schedule 11.05.2016

Благодаря предложению Дуга использовать 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.
};
person OrangeSherbet    schedule 11.05.2016