Трудно отличить терминологию, которую вы использовали, и код представлял именно то, что происходит. Поэтому, возможно, вам помогут несколько примеров.
Массив new и удаление массива
Что случилось с new []
и delete []
, спросите вы? Эти парни используются для распределения / освобождения массивов вещей. Это могут быть POD или полноценные объекты. Для объектов они будут вызывать конструктор после выделения и деструктор при освобождении.
Давайте возьмем надуманный пример:
class MrObject
{
public:
MrObject() : myName(new char[9]) { memcpy(myName, "MrObject", 9); }
virtual ~MrObject() { std::cout << "Goodbye cruel world!\n"; delete [] myName; }
private:
char* myName;
};
Теперь мы можем сделать несколько забавных вещей с MrObject.
Массивы объектов
Сначала давайте создадим красивый и простой массив:
MrObject* an_array = new MrObject[5];
Это дает нам массив из 5 MrObjects, все они хорошо инициализированы. Если мы хотим удалить этот массив, мы должны выполнить удаление массива, которое, в свою очередь, вызовет деструктор для каждого MrObject. Давайте попробуем это:
delete [] an_array;
Но что, если мы обманываем и просто делаем нормальное удаление? Что ж, сейчас самое время попробовать это для себя
delete an_array;
Вы увидите, что вызывается только первый деструктор get. Это потому, что мы не удалили весь массив, только первую запись.
Ну иногда. Это действительно не определено, что здесь происходит. Вывод состоит в том, чтобы использовать форму массива delete при использовании массива new, то же самое для простого старого new и delete.
Векторы объектов
ОК, это было весело. Но давайте теперь посмотрим на std :: vector. Вы обнаружите, что этот парень будет управлять памятью для вас, и когда он выходит из области видимости, то же самое делает и все, за что держится. Давайте возьмем его на пробную поездку:
std::vector<MrObject> a_vector(5);
Теперь у вас есть вектор с 5 инициализированными MrObjects. Давайте посмотрим, что произойдет, когда мы очистим этот присоски:
a_vector.clear();
Вы заметите, что все 5 деструкторов получили удар.
Векторы указателей на объекты
Ооооооооо вы говорите, но теперь давайте представимся. Я хочу всего хорошего в std :: vector, но также хочу управлять всей памятью сам! Ну, есть строка для этого:
std::vector<MrObject*> a_vector_of_pointers(5);
for (size_t idx = 0; idx < 5; idx++) {
// note: it's just a regular new here, not an arra
a_vector_of_pointers[idx] = new MrObject;
}
Видите, это было немного больше боли. Но это может быть полезно, вы можете использовать конструктор не по умолчанию при создании MrObject. Вместо этого вы можете поместить туда производные MrObjects. Ну, как вы можете видеть, что небо это предел. Но ждать! Вы создали эту память, вам лучше всего с ней справиться. Вы захотите перебрать каждую запись в векторе и очистить после себя:
for (size_t idx = 0; idx < a_vector_of_pointers.size(); idx++) {
delete a_vector_of_pointers[idx];
}