【问题标题】:Get error when I push element onto vector当我将元素推到向量上时出错
【发布时间】:2019-03-12 01:16:34
【问题描述】:

当我想用container.push_back(tmp); 将元素添加到向量中时,下面的代码出现is implicitly deleted because the default definition would be ill-formed 错误,这是为什么呢? 我的代码:

#include <vector>
#include <mutex>
class A {
    public:
    A(){}
    ~A(){}
};
class my_t {
    private:
        bool busy;
        bool alive;
        std::mutex bmtx;
        std::mutex amtx;
    public:
        my_t(){std::lock_guard<std::mutex>lock(bmtx);busy=false;}
        ~my_t(){}
        A* conn; 
        void take(void) {std::lock_guard<std::mutex>lock(bmtx);busy=true; }
        void give(void) {std::lock_guard<std::mutex>lock(bmtx);busy=false; }
        bool busy_get(void) {return busy;}
        void set_online(void){ std::lock_guard<std::mutex>lock(amtx); alive=true; }
        void set_OFFLINE(void) {std::lock_guard<std::mutex>lock(amtx); alive=false; }
        bool alive_get(void) {return alive;}

};

class app {
    private:
        std::vector<my_t> container;
    public: 
        app();
        ~app();
};
app::app() {
    my_t tmp;
    tmp.conn = new A();
    if (tmp.conn)
        tmp.set_online();
    container.push_back(tmp);


}
int main(void) {}

或在 Coliru 上:https://coliru.stacked-crooked.com/a/11625c77383df80c

【问题讨论】:

  • 当您推入container 时,您会尝试复制 my_t 对象。这将调用(默认的,编译器提供的)复制构造函数,但这不能存在,因为它会复制所有成员和std::mutex has a deleted copy constructor.
  • @UlrichEckhardt 老实说,我没有尝试编译它,但看起来它会编译并显示问题。它不是严格意义上的最小化,但也不是太大,只有几个额外的函数,它们是单行的。
  • 不是 MCVE,这会让你的问题在这里跑题。这是有充分理由的,请点击提供的链接!
  • 旁注:在my_t 类中包含A* conn; 表明您应该留意Rules of Three and Five。确保在解决 mutex 问题后正确复制内容。

标签: c++ class vector types


【解决方案1】:

您不能拥有my_t 对象的向量,因为my_t 类包含std::mutexes:

 std::mutex bmtx;
 std::mutex amtx;

互斥体have a deleted copy constructor。没有复制构造互斥锁这样的事情。

由于您的my_t 类也没有复制构造函数,这也会自动删除my_t 的复制构造函数。

std::vector 的值类必须至少有a copy constructor and an assign operator。这是因为向量必须能够重新分配其内容,以适应其增长。这意味着向量中的元素必须是可复制/可分配的。

如果你为你的my_t 类显式地实现了一个复制构造函数和一个赋值运算符,你就可以用它们来创建一个向量。但是你需要弄清楚复制构造和分配给你的my_t类意味着什么......

对于你的类,你能做的最多就是拥有一个指向my_t 实例的指针向量。也许使用std::unique_ptrstd::shared_ptr

【讨论】:

    【解决方案2】:

    在这一行:

    container.push_back(tmp);
    

    您尝试复制 my_t 对象。这将调用(默认的,编译器提供的)复制构造函数,但这不存在。它不能存在,因为它会一一复制所有成员,以及std::mutex has a deleted copy constructor.

    互斥体可复制没有任何意义。它们没有value semantics,只有与实际值一起存在时才有意义。

    因此,为my_t 创建您自己的复制构造函数,它会复制所有可以复制的成员,并默认构造其他成员。

    几乎可以肯定,您还想将conn 成员设为deep copy,并将其设为std::unique_ptr&lt;A&gt;,以确保在对象被破坏时正确获取deleted。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多