Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当类被销毁时,类中声明的映射容器是否被销毁?_C++ - Fatal编程技术网

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

C++ 当类被销毁时,类中声明的映射容器是否被销毁?,c++,C++,当对象a被销毁时,personsInHouse映射是否也被销毁,或者我需要在析构函数中销毁它?如果我不这样做,会不会造成内存泄漏 class A { public: map<unsigned int, unsigned int> personsInHouse; }; int main(){ A a; A.hash[10] = 23; }; A类{ 公众: 个人住宅地图; }; int main(){ A A; A.散列[10]=23; }; 是的,是的。当类

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

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

int main(){
    A a;
   A.hash[10] = 23;
};
A类{
公众:
个人住宅地图;
};
int main(){
A A;
A.散列[10]=23;
};

是的,是的。当类的析构函数运行时,其所有成员的析构函数都会运行。确切地说,顺序是:

  • 析构函数的主体已运行
  • 所有构件按与构造相反的顺序被破坏
  • 所有非虚基类,按照与构造相反的顺序,都被销毁
  • 所有虚拟基类,按照与构造相反的顺序,都将被销毁
  • 一般来说,如果没有指针,也可以预期没有内存泄漏。情况并非总是这样:您可能正在使用泄漏函数,或者某些函数可能正在执行动态分配,然后返回对对象的引用。使用智能指针可以进一步改善这种情况

    <>一个避免C++内存泄漏的有用技术是:所有标准容器都遵循它,这就是为什么在它超出范围之前,不需要显式地“代码> CULL())/CUT>容器的原因。基本原则是让类清理其析构函数中的所有资源,然后为此创建专用类,这样大多数类就不必担心了

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

    struct S {
        int* p;
    };
    

    然后,
    p
    S
    的唯一成员,当
    S
    超出范围时,
    p
    将被销毁(这通常不涉及任何事件,可能除了调整堆栈指针)。如果你在某个时候做了
    S;s、 p=新整数
    那么
    p
    仍然是唯一的成员,并且
    p
    指向的对象将不是一个,因此当
    s
    超出范围时不会被销毁。为此,您需要手动执行
    delete s.p
    ,它对应于每个需要有相应的
    删除
    的一般规则(idem表示
    新[]
    删除[]
    )。

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

    如果
    personsInHouse
    是一个指针,您使用
    new
    在动态存储中创建了一个
    map
    ,并在
    personsInHouse
    中存储了指向它的指针,那么您需要通过
    delete
    手动释放
    personsInHouse
    a
    的析构函数中指向的内存。但你发布的代码不是这样的


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

    如果其成员在动态存储中怎么办?@LuchianGrigore:那么这不是成员,而是指向对象的成员指针。正如我所说,指针已被销毁。@LuchianGrigore:成员不能在堆中,他们可以指向堆中的项(在这种情况下,指针本身实际上已被销毁,但不是它指向的对象)@Jack成员可以在堆中,如果父对象在堆中heap@Seth卡内基:它们可能作为另一个对象的一部分在堆中,但这并不能改变现状。如果父对象在按值声明时被销毁,则它们将被销毁。从技术上讲,无论它们放置在何处,personsInHouse的作用域都是父对象的作用域。但另一种说法是,答案是好的。@MooingDuck最好说“一生”,不是吗?我认为范围更多的是关于可见性。谢谢,我补充了另一行。但是对于自动存储持续时间的对象,生命周期和范围是紧密耦合的。@LightnessRacesinOrbit这是真的,但它们仍然是分开的,我仍然认为正确的词是lifetime@MooingDuck:PersonSiHouse的范围不是完整对象的范围。作用域是程序中通过名称查找可以看到名称的部分(严格来说是名称的属性,而不是名称所指对象的属性)。
    personsInHouse
    的范围是
    A
    的类定义,加上
    A
    的成员函数、派生类等的任何函数定义(在本例中没有)。它也在
    main
    中的
    a.personsInHouse
    范围内。
    a
    的范围就是
    main
    。生命是一个不同的概念,赛斯说的是生命。