2015-03-04 2 views
0

У меня есть следующий фрагмент кода:Как использовать вектор (или другой контейнер) с классом non-copyable?

void f(){ 
    ..... 
    std::vector<PrepareLogFileThread> v; 

    for(int i = 0; i < list.length(); ++i){ 

    PrepareLogFileThread a( 
       list[i], 
       LOG_TEMPLATE); 
    a.start(); 
    v.push_back(a); 
    } 
    .... 
} 

класса PrepareLogFileThread наследуется от Thread класса, который использует pthread (мы используем C++ 98 стандарт .... и я могу использовать auto_ptr).

Проблема заключается в том, что конструктор копирования Thread является закрытым, так что это не испортило выполнение или что-то (я не являюсь автором этого класса).

Идея заключается в том, что я создаю свои PrepareLogFileThread объекты, push_back на v, начать их, а затем они все закончить, прежде чем f возвращается.

PrepareLogFileThread имеет в деструкторе звонок pthread_join, так что он заканчивается там.

Но я не могу, потому что копирую a в соответствии с push_back.

Как это сделать без C++ 11 и сменить конструктор копирования Thread?

Я использую gcc 4.4.6, и могу использовать auto_ptr.

+2

Вам понадобится ваш собственный контейнер, который не требует копируемых типов и позволяет создавать на месте («размещение»), как контейнеры C++ 11. Или, возможно, добавьте уровень косвенности и указатели хранилища к динамическим объектам (осторожно удаляя их по мере необходимости, поскольку у вас нет подходящих интеллектуальных указателей). [Boost] (http://www.boost.org/doc/libs/1_57_0/doc/html/container.html) может помочь, если вы действительно застряли в прошлом. –

ответ

1

Стандартные контейнеры предполагают, что их элементы поддерживают семантику ценности (в том числе, на вашем языке, «копируемость» - между прочим).

Один из вариантов - создать собственный контейнер, который не требует такой семантики. Это сложно, по разным причинам.

В качестве альтернативы, ваши элементы контейнера должны быть чем-то другим, у которого есть семантика значения, где значение уникально идентифицирует экземпляр вашего класса PrepareLogFileThread. Очевидным выбором для такого «чего-то» является указатель. Например;

void f() 
{ 
    std::vector<PrepareLogFileThread *> v; 

    for(int i = 0; i < list.length(); ++i){ 

    PrepareLogFileThread *a = new PrepareLogFileThread( 
       list[i], 
       LOG_TEMPLATE); 
    a->start(); 
    v.push_back(a); 
    } 
} 

Имейте в виду, однако, что необходимо удалить элементы вектора v, прежде чем он перестает существовать - объекты, созданные с помощью оператора new не уничтожаются автоматически, когда сделано. В противном случае произойдет утечка памяти.

Обратите также внимание, что std::auto_ptr не поддерживает семантику значений, поэтому ее нельзя хранить в стандартном контейнере.

1

Вы можете сохранить указатель на объект.

std::vector<PrepareLogFileThread*> v; 

Вы должны быть осторожны относительно срока службы объекта.

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