当前位置:  开发笔记 > 编程语言 > 正文

delete会调用析构函数吗?

如何解决《delete会调用析构函数吗?》经验,为你挑选了4个好方法。

我有一个类(A),它为其中一个字段使用堆内存分配.A类被实例化并作为指针字段存储在另一个类(B)中.

当我完成对象B时,我调用delete,我假设调用了析构函数...但是这也调用了A类中的析构函数吗?

编辑:

从答案中,我接受了(请编辑,如果不正确):

    class A B的实例调用B :: ~B();

    哪个叫 class B

    delete 应该显式地将delete所有堆分配的成员变量A;

    最后,存储所述B实例的内存块返回到堆中 - 当使用new时,它首先在堆上分配一块内存,然后调用构造函数来初始化它,现在在调用所有析构函数来完成对象之后对象所在的块返回到堆.

Eclipse.. 180

A的析构函数将在其生命周期结束时运行.如果您希望释放其内存并运行析构函数,则必须在堆上分配它时将其删除.如果它是在堆栈上分配的,则会自动发生(即,当它超出范围时;请参阅RAII).如果它是类的成员(不是指针,而是完整成员),则在包含对象被销毁时会发生这种情况.

class A
{
    char *someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { delete[] someHeapMemory; }
};

class B
{
    A* APtr;
public:
    B() : APtr(new A()) {}
    ~B() { delete APtr; }
};

class C
{
    A Amember;
public:
    C() : Amember() {}
    ~C() {} // A is freed / destructed automatically.
};

int main()
{
    B* BPtr = new B();
    delete BPtr; // Calls ~B() which calls ~A() 
    C *CPtr = new C();
    delete CPtr;
    B b;
    C c;
} // b and c are freed/destructed automatically

在上面的示例中,需要每次删除和删除[].在我没有使用它的情况下,不需要删除(或者确实可以使用).

auto_ptr,unique_ptrshared_ptr等..非常适合做这个生命周期管理要容易得多:

class A
{
    shared_array someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { } // someHeapMemory is delete[]d automatically
};

class B
{
    shared_ptr APtr;
public:
    B() : APtr(new A()) {}
    ~B() {  } // APtr is deleted automatically
};

int main()
{
    shared_ptr BPtr = new B();
} // BPtr is deleted automatically

@TomášZato:如果你在随机指针上调用delete,那你就搞砸了.做这件事从来没有充分的理由.实际上,如果您手动调用除智能指针析构函数之外的任何位置的删除,那么您可能需要再次查看为什么不使用智能指针或其他对象管理器. (2认同)


小智.. 30

当您对由new分配的指针调用delete时,将调用指向的对象的析构函数.

A * p = new A;

delete p;    // A:~A() called for you on obkect pointed to by p


Sebastian Ma.. 22

它被命名为"析构函数",而不是"解构函数".

在每个类的析构函数中,您必须删除已使用new分配的所有其他成员变量.

编辑:澄清:

说你有

struct A {}

class B {
    A *a;
public:
    B () : a (new A) {}
    ~B() { delete a; }
};

class C {
    A *a;
public:
    C () : a (new A) {}        
};

int main () {
    delete new B;
    delete new C;
}

分配B的实例然后删除是干净的,因为B内部分配的内容也将在析构函数中删除.

但是C类的实例会泄漏内存,因为它分配了一个它不释放的A实例(在这种情况下C甚至没有析构函数).



1> Eclipse..:

A的析构函数将在其生命周期结束时运行.如果您希望释放其内存并运行析构函数,则必须在堆上分配它时将其删除.如果它是在堆栈上分配的,则会自动发生(即,当它超出范围时;请参阅RAII).如果它是类的成员(不是指针,而是完整成员),则在包含对象被销毁时会发生这种情况.

class A
{
    char *someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { delete[] someHeapMemory; }
};

class B
{
    A* APtr;
public:
    B() : APtr(new A()) {}
    ~B() { delete APtr; }
};

class C
{
    A Amember;
public:
    C() : Amember() {}
    ~C() {} // A is freed / destructed automatically.
};

int main()
{
    B* BPtr = new B();
    delete BPtr; // Calls ~B() which calls ~A() 
    C *CPtr = new C();
    delete CPtr;
    B b;
    C c;
} // b and c are freed/destructed automatically

在上面的示例中,需要每次删除和删除[].在我没有使用它的情况下,不需要删除(或者确实可以使用).

auto_ptr,unique_ptrshared_ptr等..非常适合做这个生命周期管理要容易得多:

class A
{
    shared_array someHeapMemory;
public:
    A() : someHeapMemory(new char[1000]) {}
    ~A() { } // someHeapMemory is delete[]d automatically
};

class B
{
    shared_ptr APtr;
public:
    B() : APtr(new A()) {}
    ~B() {  } // APtr is deleted automatically
};

int main()
{
    shared_ptr BPtr = new B();
} // BPtr is deleted automatically


@TomášZato:如果你在随机指针上调用delete,那你就搞砸了.做这件事从来没有充分的理由.实际上,如果您手动调用除智能指针析构函数之外的任何位置的删除,那么您可能需要再次查看为什么不使用智能指针或其他对象管理器.

2> 小智..:

当您对由new分配的指针调用delete时,将调用指向的对象的析构函数.

A * p = new A;

delete p;    // A:~A() called for you on obkect pointed to by p



3> Sebastian Ma..:

它被命名为"析构函数",而不是"解构函数".

在每个类的析构函数中,您必须删除已使用new分配的所有其他成员变量.

编辑:澄清:

说你有

struct A {}

class B {
    A *a;
public:
    B () : a (new A) {}
    ~B() { delete a; }
};

class C {
    A *a;
public:
    C () : a (new A) {}        
};

int main () {
    delete new B;
    delete new C;
}

分配B的实例然后删除是干净的,因为B内部分配的内容也将在析构函数中删除.

但是C类的实例会泄漏内存,因为它分配了一个它不释放的A实例(在这种情况下C甚至没有析构函数).



4> sharptooth..:

如果你有一个通常的指针(A*)那么析构函数将不会被调用(A例如,内存也不会被释放),除非你deleteB析构函数中明确地执行.如果你想要自动销毁,请查看智能指针auto_ptr.

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有