Повторное использование вектора в С++

У меня есть вектор, объявленный как глобальная переменная, которую я должен использовать для повторного использования. Например, я читаю несколько файлов данных, анализируя данные для создания объектов, которые затем хранятся в векторе.

vector<Object> objVector(100);

void main()
{
 while(THERE_ARE_MORE_FILES_TO_READ)
 {
    // Pseudocode
     ReadFile();
     ParseFileIntoVector();
     ProcessObjectsInVector();
     /* Here I want to 'reset' the vector to 100 empty objects again */

 }

}

Могу ли я reset вектор быть "векторным объективом (100)", поскольку он был первоначально выделен в стеке? Если я делаю "objVector.clear()", он удаляет все 100 объектов, и у меня будет вектор с размером 0. Мне нужно, чтобы он был размером 100 в начале каждого цикла.

Ответы

Ответ 1

vector<Object> objVector(100); 

int main() 
{ 
 while(THERE_ARE_MORE_FILES_TO_READ) 
 { 
    // Pseudocode 
     ReadFile(); 
     ParseFileIntoVector(); 
     ProcessObjectsInVector(); 
     /* Here I want to 'reset' the vector to 100 empty objects again */ 
     objVector.clear();
     objVector.resize(100);

 } 
}

Ответ 2

У меня есть вектор, объявленный как глобальная переменная, которую я должен использовать для повторного использования.

Почему? Из вашего кода неясно, почему переменная должна быть глобальной. Почему вы не можете объявить его внутри цикла? Тогда вам не понадобится reset it, это будет сделано автоматически в каждом цикле.

Чтобы получить доступ к переменной из других методов, передайте ее как параметр (по ссылке, чтобы вы могли ее изменить). Наличие глобальной переменной редко является хорошим решением.

Что-то еще: main должен никогда иметь тип возвращаемого значения void, это недопустимо С++, и многие компиляторы его отклонят.

Ответ 3

objVector.clear();
objVector.resize(100);

Однако, это, вероятно, не рекомендуется использовать вектор. Вы уверены, что не следует использовать push_back с вектором, который изначально пуст? Как вы можете быть уверены, что каждый файл содержит ровно 100 объектов, не более того, как это видно из вашего вопроса?

Вектор, вероятно, также не должен быть глобальным. Лучше все обойти. Когда вы видите кучу функций, называемых без параметров, довольно сложно, если не невозможно, следить за тем, что происходит (потому что все остальные, кроме вас, включая вас, когда вы вернетесь к этому коду через несколько месяцев, будут иметь не знаю, что эти функции используют для ввода и что такое выход).

Ответ 4

Изменение размера звонка в начале или конце цикла: http://www.cplusplus.com/reference/stl/vector/resize/

Это должно делать то, что вы хотите. Однако я бы рекомендовал использовать функции push и pop. Он более эффективен в пространстве и как предполагается использовать вектор. Вектор будет расширяться и уменьшаться по мере необходимости, когда вы нажимаете (добавляете) и извлекаете (удаляете) предметы из него. Таким образом, вам не нужно беспокоиться о размере или содержании вектора. Он просто становится очереди обработки.

Ответ 5

Почему вы пытаетесь использовать reset глобальную переменную? Просто выделите новый вектор каждый раз через цикл и передайте вектор в функции по ссылке.

void ParseFileIntoVector(vector<Object> &vector);
void ProcessObjectsInVector(const vector<Object> &vector);

int main() 
{ 
 while(THERE_ARE_MORE_FILES_TO_READ) 
 { 
     // Pseudocode 
     vector<Object> objVector(100); 
     ReadFile(); 
     ParseFileIntoVector(objVector); 
     ProcessObjectsInVector(objVector); 
 } 
}

Ответ 6

Следующий код должен сделать трюк.

vector<Object> temp(100);
objVector.swap(temp);

Ответ 7

В отличие от других сообщений, самый эффективный способ сделать это, вероятно, это:

objVector.resize(0);
objVector.resize(100);

clear() освобождает память от вектора на некоторых реализациях (его единственным необходимым условием является то, что size() = 0). resize (0) поддерживает емкость.

Сводка подкачки также вызывает ненужное выделение памяти. Временный вектор, который вы поменяете, будет выделять новый блок памяти, а после его замены также будет освобожден старый блок памяти. Производительность должна быть лучше без выделения памяти.

Ответ 8

Вызовите objVector.clear(), чтобы удалить предыдущие точки данных, а затем objVector.resize(100), чтобы изменить его размер до соответствующего размера.

Обратите внимание, что это будет выделение 1 экземпляра Object с использованием конструктора по умолчанию, а затем 100 копий Object с использованием конструктора копирования, который может или не может быть тем, что вы действительно хотите. Необязательно, если Object является типом указателя, вы можете использовать objVector.resize(100, NULL), чтобы избежать возможных нежелательных распределений.

Ответ 9

Поскольку вы используете конструктор по умолчанию для "Объект", я думаю, вы должны полагаться на емкость вектора вместо его размера. Таким образом, когда вы вызываете clear(), скорее всего, вы не меняете емкость, заданную вашим векторным конструктором (вы можете удерживать не менее 100 элементов, они уже выделены). Читайте о емкости, резерве и размере и о том, как они отличаются друг от друга (резерв - это вызов, который вы хотите запросить для изменения емкости, я просто укажу его на случай, если вам это нужно).

В любом случае, если вам нужно reset ваши объекты в состояние по умолчанию, а не полагаться на способность делать векторный объект reset объектов, вы также можете просто позвонить на свой объект называемый "reset", чтобы установить их в это состояние и вызвать его перед повторной обработкой с использованием тех же объектов. По производительности, я не вижу в этом ничего другого, и по коду это кажется чистым решением.

Ответ 10

Могу ли я reset, чтобы вектор был "вектором objVector (100)", поскольку он был первоначально выделен в стеке?
  • Вложенные векторы С++ не выделяются в стеке. По крайней мере, не напрямую. Одним из параметров для вектора (и других шаблонов STL) является распределитель. Вы можете использовать распределители пулов, распределители кучи и т.д.

    std::vector<T> на самом деле красиво упакованный указатель на массив с дополнительной информацией (например, размер и емкость). В противном случае размер вектора должен был быть известен заранее (что не требуется).

  • Фактически в приведенном выше примере std::vector<T> не находится в стеке, а в разделе данных программы (или как он называется на платформах, отличных от ELF).

Итак, вопрос в том, что вам нужно:

  • Вектор размером 100. В этом случае, как было указано, вполне вероятно, что вы делаете что-то странное. Но это все еще возможно с помощью метода resize.
  • Вектор емкости 100. В этом случае вы, вероятно, ничего не должны делать, поскольку векторы не уменьшают его способность AFAIR. И, конечно же, это не требуется, так как векторы динамически меняют свою емкость.