假设我们有一个类:
class MyClass1
{
int a;
string s;
...
};
class MyClass2
{
list<MyClass1> lst;
}
MyClass2
声明将完全破坏容器的析构函数的正确方法是什么?就个人而言,我是这样写的:
~MyClass2()
{
this->lst.clear();
this->lst.shrink_to_fit();
}
但this->lst.clear();
它为每个容器对象调用析构函数,并且
this->list.shrink_to_fit();
根据size
. 但是,例如,当size=0, capacity=1
,即在任何情况下,容器将在内存中,即使“有条件地” - 其中没有元素。
问题:如何从内存中完全删除容器?
在
shrink_to_fit
一个空容器之后capacity
,它将等于 0。并且MyClass2
您不需要在类析构函数中编写任何内容,因为列表析构函数会自行清理所有内容。这不是我第一次注意到这种情况,由于某种原因,在包含容器(类型等)的类的析构函数中执行手动清理,这些容器
std::vector
控制std::list
其对象的生命周期。在大多数情况下,这不是必需的;当包含容器的对象死亡时,容器也会自动被杀死。容器析构函数依次调用当时包含的容器元素的析构函数,以此类推。因此,如果容器元素具有(或不需要)完全破坏自身的析构函数,则不需要手动操作。但是,如果,比如说,由于某种原因,您在容器中存储了一些原始指针之类的东西,之前为其分配了内存,那么当然,这些指针需要
delete
在有关它们的信息(内存所在的地址)之前被释放(执行适当的形式)已分配)将被容器的析构函数销毁。特别是,以适当的周期完成它们。但即使在这种情况下,最好依靠适当的智能指针(例如,std::unique_ptr
或std::shared_ptr
)来避免不必要的手动破坏工作(编写析构函数)。如果列表容器准确地存储了 MyClass1 的元素,而不是指向它们的指针,那么在析构函数中不需要对这个容器做任何事情,它会在 MyClass2 类型对象被销毁时清理所有内容。
编译器会生成一些“默认”代码来支持 OOP。如果您不声明自己的自定义析构函数,则包括默认析构函数。默认析构函数调用类的所有实例字段的析构函数,即 在你的情况下和
list
。并且
std::list
,反过来,它足够聪明,可以自行清理,所以你的任务只是实现析构函数的逻辑,MyClass1
如果需要,它的实例存储在一个列表中(MyClass1
包含需要手动释放的非托管资源)。