当类被销毁时,类中声明的映射容器是否被销毁?

时间:2012-02-19 15:03:12

标签: c++

当对象a被破坏时,personsInHouse地图是否也被破坏,或者我需要在析构函数中销毁它?如果我不这样做会造成内存泄漏吗?

class A {
public:
    map<unsigned int, unsigned int> personsInHouse;
};

int main(){
    A a;
   A.hash[10] = 23;
};

2 个答案:

答案 0 :(得分:5)

personsInHouse的生命周期自动,因为您将按值存储,其生命周期是父对象的生命周期。因为您通过值创建a ,所以当它超出范围时会调用它的析构函数,并且对象的析构函数会自动调用它包含的对象的析构函数。因此,您不需要销毁personsInHouse,就像您不需要销毁a一样。

如果personsInHouse指针并且您使用map<unsigned int, unsigned int>动态存储空间中创建了new并存储了指针在personsInHouse中,您需要通过personsInHouse手动释放Adelete的析构函数中指向的内存。但是在您发布的代码中并非如此。

您所做的是做到这一点的好方法:更喜欢按值存储您可以使用的每个对象,这样您就不必担心动态对象的生命周期管理。

答案 1 :(得分:4)

是的,确实如此。运行类的析构函数时,将运行其所有成员的析构函数。确切地说,订单是:

  1. 运行析构函数的主体
  2. 所有成员,按照相反的施工顺序,被破坏
  3. 违反构造的所有非虚拟基类被破坏
  4. 所有虚拟基类(以相反的构造顺序)被破坏
  5. 一般情况下,如果你没有指针,你也可以期望没有内存泄漏。情况并非总是如此:您可能正在使用泄漏函数,或者某些函数可能正在执行动态分配,然后返回对该对象的引用。使用智能指针可以进一步改善这种情况。

    在C ++中避免内存泄漏的一种有用技术是RAII:所有标准容器都遵循它,这就是为什么在容器超出范围之前不需要显式clear()容器。基本原则是让类在其析构函数中清理所有资源,然后为其创建专用类,以便大多数类不必担心它。

    请注意,“类成员”是在类范围内定义的严格非静态成员。如果你有

    struct S {
        int* p;
    };
    

    然后pS的唯一成员,当S超出范围时,p将被销毁(通常不会涉及任何事情,除了可能调整堆栈指针之外)。如果您在某个时间点S s; s.p = new int;,那么p仍然是唯一的成员,p指向的对象将为一个,因此s超出范围时不被销毁。要实现这一点,您需要手动执行delete s.p;,这与每个new的一般规则相对应,需要具有相应的deletenew[]的同一性{和} { {1}})。