Я имею abstract
Base
класс и Derived
класс.
int main ()
{
Base *arrayPtr[3];
for (int i = 0; i < 3; i++)
{
arrayPtr[i] = new Derived();
}
//some functions here
delete[] arrayPtr;
return 0;
}
Я не уверен, как использовать оператор delete. Если я удалю массив указателей базового класса как показано выше, то это назовет деструкторы объектов производного класса и уберет память?
] Нужно выполнить итерацию над элементами массива, [] удалить [
] каждый из них. Затем вызвать [], если массив был динамически выделен, вызов [] delete [][
], используя [] new[][
]. [][
] В вашем примере кода массив выделен на стеке, поэтому нельзя вызывать [] delete [][
] на нем.[
] Также убедитесь, что ваш класс [] Base[
] имеет [] виртуальный[
] деструктор.[
] Ссылка: []Когда мой деструктор должен быть []виртуальным[
][].[
]Вы смешиваете парадигмы -- Оператор delete массива предназначен для освобождения памяти, выделяемой оператором new массива, но вы выделяете массив на стеке как массив указателей, а затем выделяете объект для каждого члена массива. В коде необходимо выполнить итерацию через массив.[
] []Чтобы использовать оператор array new, нужно объявить так:[
] [Base *array;
array = new Base[3];
/* do stuff */
delete[] array;
]
[]Это выделяет сопряженную область памяти для трех объектов -- обратите внимание, что у вас есть массив объектов Base, а не массив указателей на объекты Base.[
].]Нет, это не совсем то, что вы хотите. [
] []Здесь нужно обратить внимание на два момента:[
] []Синтаксис []delete[] arrayPtr[
] используется, если вы динамически выделяете массив, например:[
][]arrayPtr = new (Base *)[mylength];
[
][
]
[]В вашем случае, однако, есть статически выделенный массив, поэтому нет необходимости его удалять. Однако необходимо удалять отдельные элементы массива:[
] [][]for ( int = i; i < 3; i++ )
удалить arrayPtr[i];
[
][
][]Второй момент, о котором необходимо позаботиться, это сделать деструктор класса []Base[
] виртуальным:[
][]class Base
{
виртуальная ~Base();
/* ... */
};
[
][
]
[]Это гарантирует, что при вызове delete на []Base *[
], который на самом деле указывает на []Derived[
], будет вызван деструктор []Derived[
], а не только деструктор []Base[
].[
]Нет, вы должны явно удалить каждый элемент массива:[
] [for (int i = 0; i < 3; ++i)
{
delete arrayPtr[i];
}
] ]Вместо этого нужно сделать:[
] [ for ( int = i; i < 3; i++ )
{
delete arrayPtr[i];
}
]
[]И не делать []delete[] arrayPtr;[
], так как вы пытаетесь освободить/удалить выделенный стек []arrayPtr[
].[
]Вместо массива следует использовать []std::vector[
] указателей. А если Вы используете компилятор, реализующий TR1, то вместо сырых указателей можно использовать []std::vector[
] из []std::tr1::shared_ptr[
], и тогда Вам не нужно будет беспокоиться об удалении этих объектов самостоятельно.[
]Пример:[
] [{
std::vector< std::tr1::shared_ptr<Base> > objects;
for (int i=0; i < 3; ++i)
{
objects.push_back(std::tr1::shared_ptr<Base>(new Derived()));
}
} // here, once "objects" exit scope, all of your Derived objects are nicely deleted
] ]Необходимо удалять члены массива по отдельности. Также необходимо убедиться, что в базовом классе имеется виртуальный деструктор. Также можно подумать о том, чтобы сделать его массивом (а еще лучше - std::vector) умных указателей, таких как boost::shared_ptr.[
].] Нет, так нельзя. Как предлагали другие, вы должны просмотреть каждый пункт и удалить его. Это очень простое правило для запоминания. Если вы выбрали []new[
], то используйте [] delete[
], а если вы использовали [] new[][
], то используйте [] delete[][
][
] Заметьте, что отсутствует:[
] [int main() {
boost::ptr_vector<Base> v;
for (int i = 0; i < 3; i++) v.push_back(new Derived());
// some functions here, using v[0] through v[2]
}
]
[] Проверьте [] контейнеры указателей Boost[]. [
]]Оператор delete должен совпадать с оператором new на этом указателе, если он был выделен с []new[][
], то вы должны вызвать []delete[][
] и наоборот;[
int* pInt = new int;
delete pInt; OK
delete [] pInt; WRONG
int[] pIntArr = new int[3];
delete [] pIntArr; OK
delete pIntArr; WRONG
]
[]В вашем случае что-то не так - вы пытаетесь []удалить [
], который был выделен на стеке. Это не сработает.[
]В данном случае вы должны удалить каждый указатель по отдельности.[
]] То, что у вас есть, является неопределенным поведением -- ошибка. Каждый вызов на []new[
] должен быть сопоставлен с []delete[
]; каждый вызов на []new[][
] должен быть сопоставлен с []delete[][
]. Они разделены и не могут быть смешаны.[
]В выложенном вами коде на стеке выделен массив указателей на Base. Затем вы вызываете []delete[][
] на массив, выделенный на стеке -- вы не можете этого сделать. Вы можете только []delete[][
] массив, выделенный на куче с помощью []new[][
]. [
]Для каждого элемента, выделенного с []new[
] -- или предпочтительнее использовать контейнерный класс, такой как []std::vector[
], вместо массива нужно вызвать []delete[
]. [
]Убедитесь, что в []Base[
] есть виртуальный деструктор. Затем, как и в случае с []fretje, описанным[], удаляем каждый элемент массива, затем массив.[
]Для массива следует использовать []std::vector[
]. При этом следует использовать []действительно [] контейнер, созданный для такого рода вещей. (Чтобы случайно не удалить все элементы, что определенно произойдет, если будет выброшено исключение!). В Boost есть []такая библиотека [].[