Мьютекс как атрибут объекта и вектор объектов - PullRequest
0 голосов
/ 04 мая 2019

Я работаю над проектом управления книжным магазином с несколькими потоками.У меня есть класс, Shelf (), который содержит мьютекс в качестве атрибута.При компиляции я получаю следующую ошибку:

error: use of deleted function 'Shelf& Shelf::operator=(const Shelf&)'
    *__result = *__first;

note: 'Shelf& Shelf::operator=(const Shelf&)' is implicitly declared as deleted because 'Shelf' declares a move constructor or move assignment operator
class Shelf {

Моя структура проекта выглядит следующим образом:
1. Book () имеет несколько строк, таких как: name, genre ...
2. Shelf() имеет: изменяемый мьютекс и unordered_map идентификаторов и Book *
3. Библиотека () имеет: вектор объектов Shelf.
Я видел здесь Как мне обращаться с мьютексами в подвижных типах в C ++? что мьютексы не являются копируемыми / перемещаемыми, поэтому я следовал инструкциям ответа @HowardHinnant.

typedef std::unordered_map<Id_t, Book *> hash_map_books_t;
class Shelf {

    using MutexType = std::mutex;
    using ReadLock = std::unique_lock<MutexType>;
    using WriteLock = std::unique_lock<MutexType>;

private:
    //ATTRIBUTES

    mutable MutexType m_mutex;
    std::string m_genre;
    hash_map_books_t m_shelf;

public:

    //CONSTRUCTORS & MOVE & COPY & DESTRUCTORS

    Shelf() = default;

    ~Shelf(){
        for (auto b : m_shelf) {
            delete b.second;
        }
        m_shelf.clear();
    }

    Shelf(Shelf &&shelf) noexcept{

        WriteLock rhs_lk(shelf.m_mutex);

        m_genre = std::move(shelf.m_genre);
        m_shelf = std::move(shelf.m_shelf);

    }

    Shelf(const Shelf &a){

        ReadLock rhs_lk(a.m_mutex);
        m_genre = a.m_genre;
        m_shelf = a.m_shelf;
    }
    Shelf& operator=(Shelf &&a) noexcept{

        if (this != &a) {
            WriteLock lhs_lk(m_mutex, std::defer_lock);
            WriteLock rhs_lk(a.m_mutex, std::defer_lock);

            std::lock(lhs_lk, rhs_lk);

            m_genre = std::move(a.m_genre);
            m_shelf = std::move(a.m_shelf);
        }
        return *this;
    }
};

И даже если мой вопрос не является целью, я открыт для других структур, которые вы могли бы сказатья.

1 Ответ

1 голос
/ 04 мая 2019

Как объясняется в сообщении об ошибке, вам необходимо указать оператор копирования, например ::1001

Shelf& operator= (const Shelf &a)
{
    if (this != &a)
    {
        WriteLock lhs_lk (m_mutex, std::defer_lock);
        ReadLock rhs_lk (a.m_mutex, std::defer_lock);
        std::lock (lhs_lk, rhs_lk);

        m_genre = a.m_genre;
        m_shelf = a.m_shelf;
    }
    return *this;
}

Наличие либо определяемого пользователем конструктора перемещения, либо определяемого пользователем оператора назначения перемещения делает это необходимым. У вас есть оба.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...