Вы, кажется, немного смущены.Здесь действуют две концепции:
- Как мне, владельцу
tmp
, освободить объекты, на которые указывают указатели в пределах tmp
? - Что следуетдеструктор для класса
object
(~object
) do?
Это на самом деле не связано.Когда вы закончите работу с вектором tmp
, вы должны вручную пройти и вызвать delete
для каждого из его элементов, чтобы освободить память, занятую объектом object
, на который указывает элемент.Это предполагает, что элементы были выделены с помощью new
, конечно.
Цель деструктора object
~object
- освободить все, что принадлежит объекту object
, не чтобы освободить сам object
объект.Если объект object
не владеет никакими динамически распределенными данными, ему не нужно ничего делать.
Другими словами, когда вы пишете delete tmp[i]
, происходят две вещи:
*(tmp[i])::~object()
называется - Память, на которую указывает
tmp[i]
, освобождается
Обратите внимание, что (2) происходит, даже если (1) абсолютно ничего не делает.Суть шага (1) состоит в том, чтобы позволить объекту, который должен быть удален, освободить любой из его объектов-членов, которые должны быть освобождены.Задача деструктора состоит в том, чтобы не решительно освобождать объект, на который он был вызван.
В явном примере:
class object {
private:
int foo;
public:
object() : foo(42) {}
~object() { /* nothing to do here; foo is not dynamically allocated */ }
};
int main() {
vector<object*> tmp;
tmp.push_back(new object());
// Do some stuff with tmp
for (int i = 0; i < tmp.size(); ++i) {
delete tmp[i]; // Calls ~object and deallocates *tmp[i]
}
tmp.clear();
return 0;
}
Или, напротив,
class object {
private:
int* foo;
public:
object() : foo(new int()) { *foo = 42; }
~object() {
// Now since foo is dynamically allocated, the destructor
// needs to deallocate it
delete foo;
}
};
int main() {
vector<object*> tmp;
tmp.push_back(new object());
// Do some stuff with tmp
for (int i = 0; i < tmp.size(); ++i) {
delete tmp[i]; // Calls ~object (which deallocates tmp[i]->foo)
// and deallocates *tmp[i]
}
tmp.clear();
return 0;
}