繁体   English   中英

将“std::mutex”作为成员字段添加到唯一可移动的类中,无需手动编码“移动构造函数”(std::unique_ptr<> 很难看)

[英]add "std::mutex" as a member field into an only-movable class without manually code "move constructor" (std::unique_ptr<> is ugly)

按照设计, B类是不可复制但可移动的。

最近,我喜欢B自动生成的移动构造函数和移动赋值运算符。

现在,我将std::mutex添加到B类。
问题是std::mutex不能移动。

#include <iostream>
#include <string>
#include <vector>
#include <mutex>
class C{
    public: C(){}
    public: C(C&& c2){ }
    public: C& operator=(C&& c2){ return *this; }
    //: by design, I don't allow copy, can only move
};
class B{public: int a=0;
    C c;
    //------ 10+ trivial fields ---
    //private: std::mutex mutexx;  //<=== uncomment = uncompilable
};
int main(){
   B b1;
   B b2;
   b1=std::move(b2);
}

有没有办法让它编译?

我可怜的解决方法1(手动)

手动创建 2 个移动函数。

class B{public: int a=0;
    C c;
    //------ 10+ trivial fields ---
    private: std::mutex mutexx;
    public: B(B&& b2){
         this->c=std::move(b2.c); 
         //--- copy other trivial fields (long and hard to maintain) --
         //:: intentionally omit move/copy of mutex
    }
    public: B& operator=(B&& b2){ ... }
};

这种解决方法会产生我想要的效果。

我可怜的解决方法 2 (unique_ptr)

使用std::unique_ptr<std::mutex> ,但有 3 个小缺点:-

  1. 十分难看
  2. 添加一些额外的堆和 CPU 成本。 代价可能很小,但我会永远怨恨它。
  3. 我还需要将我的一些代码从mutexx.lock()重构为mutexx->lock()

编辑:我可怜的解决方法3(封装互斥锁)

(得到第一个答案后添加)

std::mutex封装到一个新类中,并创建 2 个什么都不做的移动函数。

如果未来的读者可能会使用这种方法,请注意我的问题本身是有问题的。
感谢“ALX23z”和“j6t”的警告。

我喜欢 B 有自动生成的移动构造函数

为什么不重命名class B并将其用作基类?

#include <iostream>
#include <string>
#include <vector>
#include <mutex>
class C{
    public: C(){}
    public: C(C&& c2){ }
    public: C& operator=(C&& c2){ return *this; }
    //: by design, I don't allow copy, can only move
};
class B1{public: int a=0;
    C c;
    //------ 10+ trivial fields ---
};

class B : public B1 {
    public: B& operator=(B&& b2){ return *this; }
    private: std::mutex mutexx;
};

int main(){
   B b1;
   B b2;
   b1=std::move(b2);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM