【发布时间】:2011-01-26 00:34:54
【问题描述】:
如果我删除一个导致其析构函数被调用的对象,内存是在析构函数完成函数中的任何操作之前还是之后释放?
【问题讨论】:
标签: c++ destructor
如果我删除一个导致其析构函数被调用的对象,内存是在析构函数完成函数中的任何操作之前还是之后释放?
【问题讨论】:
标签: c++ destructor
只有在最小派生类子对象被销毁后才会释放内存。所以如果你有:
class Base {
};
class Derived : public Base {
public:
~Derived();
};
然后首先 Derived 被销毁,然后 Base 被销毁,然后才释放内存。
【讨论】:
class test { string a; ~test() {} }; ~test 析构函数在此示例中完美定义,没有资源直接由班级管理,什么也不做。在~test 完成执行后,系统将在a 子对象上调用~string,而不是~test。继承也是一样,会自动调用base的析构函数。
base 的析构函数都以相反的构造顺序被调用。回到责任上,如果一个成员拥有一个需要特定管理的资源,并且该资源不被该类型的析构函数持有——想想一个需要 delete 的指针,并且作为一个指针没有析构函数—— - 然后该资源必须在包含类中进行管理。
~Derived() 内明确调用this->~Base()。但是,至少按照正式定义的方式,~Derived() 负责调用this->~Base()(以及您的评论示例中的a.~string())。当您使用delete 时,会调用一个析构函数,该析构函数负责调用所有清理,包括在需要时调用任何基类或成员析构函数。
将delete分解成它实际在做的事情,看看什么时候删除内存就比较清楚了。所以这样的声明:
delete some_ptr;
大致相当于这个伪代码:
some_ptr->~some_ptr();
free( some_ptr );
所以内存在调用析构函数后被释放。析构函数的确切作用不是由delete 运算符决定,而是由类的定义决定。通常它会进行本地清理并确保其基类析构函数也被调用。
重要的是要意识到释放内存实际上并不是析构函数的一部分。释放内存的是delete 运算符。
请注意,伪代码中的free 函数实际上是operator delete() 函数之一,用于已删除的类或全局。这实际上释放了内存。
【讨论】:
free(),那是operator delete()。
operator delete() - 全局或特定于类 - 在 delete 语句上释放内存。
在析构函数完成后,内存被释放。否则,在析构函数中访问成员变量会导致段错误。
【讨论】:
在析构函数之后调用操作符delete,但释放内存时取决于使用的分配器
【讨论】:
我认为在析构函数本身完成执行后释放内存。我知道当捕获到异常时,直到对象本身超出范围时才会调用对象的析构函数。
【讨论】:
在 C++ 中,销毁是关于使用对象中可用的数据执行一些代码。这段代码是任意的。
释放内存是一种低级处理,通常被 delete 运算符隐藏,绝不应在调用析构函数之前调用它。
Allocator 接口最好总结了这一点:
allocate 和 deallocate 用于操作原始内存construct和destroy用于调用对象的构造函数和析构函数确切地说,construct、destroy 和 deallocate 只能在该分配器先前分配的内存上执行。它还明确指出destroy 不会释放内存,并且随后需要调用deallocate。
请注意,这是一个低级接口,它允许销毁一个对象并重用释放的空间来构建另一个对象。
【讨论】: