sutex作为对象属性和对象的向量

Mutex as object attribute and vector of objects

本文关键字:对象 向量 属性 sutex      更新时间:2023-10-16

我正在研究一个带有多个线程的书店管理项目。我有一个shelf((的类,其中包含一个sutex作为属性。当我编译时,我会收到以下错误:

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((有一些字符串,例如:名称,类型...
2.架子((具有:Mutable Mutex和ID和书籍的Unordered_map*
3.库((有:架子对象的向量。
我在这里看到了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;
    }
};

,即使不是我问题的目的,我也会为您可以告诉我的其他结构开放。

正如错误消息所解释的那样,您需要提供复制分配操作员,例如:

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;
}

存在用户定义的移动构造函数或用户定义的移动分配操作员的存在使得这是必要的。你们两个。