如何向此类添加复制构造函数和赋值运算符?

Posted

技术标签:

【中文标题】如何向此类添加复制构造函数和赋值运算符?【英文标题】:How do I add a copy constructor and assignment operator to this class? 【发布时间】:2010-11-01 03:02:31 【问题描述】:

我在向此类添加复制构造函数时遇到问题: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html

我需要添加它,以便可以将 concurrent_queue 添加到 stl 矢量容器中。 尝试了以下,它几乎可以编译。事实上,如果我从它编译的复制构造函数中删除 the_mutex 和 the_condition_variable。当我重新添加它时,它不会。赋值运算符在编译方面似乎没问题。

concurrent_queue(concurrent_queue<Data> const& rhs):
    the_queue(rhs.the_queue),
    the_mutex(rhs.the_mutex),
    the_condition_variable(rhs.the_condition_variable)



concurrent_queue<Data>& operator = (concurrent_queue<Data> const& rhs)

    if (this == &rhs) return *this; // check for self assignment

    the_queue = rhs.the_queue;
    the_mutex(rhs.the_mutex);
    the_condition_variable(rhs.the_condition_variable);

我得到的错误如下:

concurrentqueue.h: In copy constructor ‘concurrent_queue<Data>::concurrent_queue(const concurrent_queue<Data>&) [with Data = Packet*]’:
/usr/include/c++/4.4/bits/stl_construct.h:74:   instantiated from ‘void std::_Construct(_T1*, const _T2&) [with _T1 = concurrent_queue<Packet*>, _T2 = concurrent_queue<Packet*>]’
/usr/include/c++/4.4/bits/stl_uninitialized.h:187:   instantiated from ‘static void std::__uninitialized_fill_n<<anonymous> >::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = concurrent_queue<Packet*>*, _Size = long unsigned int, _Tp = concurrent_queue<Packet*>, bool <anonymous> = false]’
/usr/include/c++/4.4/bits/stl_uninitialized.h:223:   instantiated from ‘void std::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = concurrent_queue<Packet*>*, _Size = long unsigned int, _Tp = concurrent_queue<Packet*>]’
/usr/include/c++/4.4/bits/stl_uninitialized.h:318:   instantiated from ‘void std::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, std::allocator<_Tp2>&) [with _ForwardIterator = concurrent_queue<Packet*>*, _Size = long unsigned int, _Tp = concurrent_queue<Packet*>, _Tp2 = concurrent_queue<Packet*>]’
/usr/include/c++/4.4/bits/stl_vector.h:1035:   instantiated from ‘void std::vector<_Tp, _Alloc>::_M_fill_initialize(size_t, const _Tp&) [with _Tp = concurrent_queue<Packet*>, _Alloc = std::allocator<concurrent_queue<Packet*> >]’
/usr/include/c++/4.4/bits/stl_vector.h:230:   instantiated from ‘std::vector<_Tp, _Alloc>::vector(size_t, const _Tp&, const _Alloc&) [with _Tp = concurrent_queue<Packet*>, _Alloc = std::allocator<concurrent_queue<Packet*> >]’
test.cpp:18:   instantiated from here
concurrentqueue.h:24: error: no match for call to ‘(boost::mutex) (boost::mutex&)’

编辑: 似乎 boost mutex 继承了我认为是相同的不可复制和条件变量。 有趣的是,在作业中我可以复制它。为什么还要编译?对于我使用它的情况,我是否需要担心它在实践中是不可复制的?

【问题讨论】:

没有必要编写其中任何一个:编译器无论如何都会发出代码来复制成员,如果它是合法的。您需要做的是编写合法代码,如其他答案所示。 【参考方案1】:

boost::mutexboost::condition_variable 都只有默认构造函数。除此之外,您不希望复制它们的(可能锁定的)状态 - 只需使用默认构造函数即可。

另外你不应该直接复制the_queue,因为这不是线程安全的。

【讨论】:

【参考方案2】:

AFAIK、boost::mutexboost::condition 不可复制(无论如何复制互斥锁没有意义)。使用复制构造函数中的默认构造函数构造它们,如下所示:

concurrent_queue(concurrent_queue<Data> const& rhs):
    the_queue(rhs.the_queue),
    the_mutex(),
    the_condition_variable()


请注意,problems 使复制构造函数线程安全。但是,如果您不在线程之间复制对象,那应该不是问题。按照previous question 中的想法,所有concurrent_queueobjects 都是预先分配的,这应该不是问题。

【讨论】:

以上是关于如何向此类添加复制构造函数和赋值运算符?的主要内容,如果未能解决你的问题,请参考以下文章

如何利用模板复制&移动构造函数和赋值运算符?

复制构造函数与赋值运算符(=)有何不同

赋值运算符和复制构造函数有啥区别?

复制构造函数和赋值运算符

c++中拷贝构造函数和赋值运算符重载本质上一样么

初始化列表:复制构造函数和赋值运算符 = 冗余?