6.4. Хранение указателей в векторе

We use cookies. Read the Privacy and Cookie Policy

6.4. Хранение указателей в векторе

Проблема

С целью повышения эффективности или по другим причинам невозможно хранить копии объектов в vector, но их требуется как-то разместить.

Решение

Сохраните в vector указатели на объекты, а не копии самих объектов. Но при этом не забудьте удалить объекты с помощью delete, так как vector этого за вас не сделает. Пример 6.4 показывает, как объявить vector указателей и работать с ним.

Пример 6.4. Использование векторов указателей

#include <iostream>

#include <vector>

using namespace std;

static const int NUM_OBJECTS = 10;

class MyClass { /*...*/ };

int main() {

 vector<MyClass*> vec;

 MyClass* p = NULL;

 // Загрузить в vector объекты MyClass

 for (int i = 0; i < NUM_OBJECTS; i++) {

  p = new MyClass();

  vec.push_back(p);

 }

 // Выполнить обработку данных, затем удалить объекты, когда

 // они уже не нужны

 for (vector<MyClass*>::iterator pObj = vec.begin();

  pObj != vec.end(); ++pObj) {

  delete *pObj; // заметьте, что здесь удаляется то на что указывает pObj,

                // который является указателем

 }

 vec.clear(); // Очистить содержимое, чтобы больше никто не попытался

              // удалить его еще раз

}

Обсуждение

Сохранить указатели в vector можно точно так же, как и все остальное. Объявите vector указателей таким образом:

vector<MyClass*> vec;

Здесь важно запомнить, что vector хранит значения, не обращая внимания на то, что они означают. Следовательно, он не знает, что для указателей перед их удалением следует использовать delete. Если выделить память, затем поместить указатели в память vector, то по окончании работы следует самостоятельно удалить память. Не дайте ввести себя в заблуждение термину «контейнер», думая, что если в vector сохранить указатель, то это подразумевает владение им.

После удаления указателей следует явно очистить vector — по той же причине, по которой следует присваивать переменным-указателям по окончании работы с ними значение NULL. Это предотвратит ошибочное повторное удаление.