2010-11-01 2 views
1

У меня возникли проблемы при добавлении конструктора копирования для этого класса: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.htmlКак добавить конструктор копирования и оператор присваивания этому классу?

Мне нужно, чтобы добавить его, так что я могу добавить concurrent_queue в СТЛ вектор контейнере. Пробовал ниже, и он почти компилируется. Фактически, если я удаляю 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&)’ 

EDIT: Похоже, что повышение мьютекс наследует, не копируемыми и состояние переменной я думаю, что это то же самое. Интересно, что в задании я могу его скопировать. Зачем это даже компилировать? Должен ли я беспокоиться о том, что он не копируется на практике для ситуации, в которой я его использую?

+0

Не нужно было писать ни одно из них: компилятор бы испустил код, чтобы копировать член-мудрый, если он был законным. Что вам нужно было сделать, это написать * юридический * код, как показано в других ответах. – EJP

ответ

2

Оба boost::mutex и boost::condition_variable имеют только конструкторы по умолчанию. Помимо этого, вы не хотите, чтобы их (потенциально заблокированное) состояние было скопировано - просто используйте конструкторы по умолчанию.

Также вы не должны копировать the_queue непосредственно, так как это не является потокобезопасным.

1

AFAIK, boost::mutex и boost::condition не могут быть скопированы (и в любом случае нет смысла копировать блокировку мьютекса). Построить их, используя конструктор по умолчанию в конструкторе копирования следующим образом:

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

Обратите внимание, что есть problems с созданием копии конструктор поточно. Если вы не копируете объекты между потоками, это не должно быть проблемой. Следуя идее в вашем previous question, где все объекты concurrent_queue предварительно выделены, это не должно быть проблемой.

Смежные вопросы