bob*_*obo 15 c++ destructor memory-management
假设你有一个对象class Fool.
class Fool
{
int a,b,c;
double* array ;
//...
~Fool()
{
// destroys the array..
delete[] array ;
}
};
Fool *fool = new Fool() ;
Run Code Online (Sandbox Code Playgroud)
现在,我知道你不应该,但有些傻瓜fool无论如何都会调用析构函数. fool->~Fool();.
这是否意味着fool释放了内存,(即a,b,c无效)或者这是否意味着只有~Fool()函数中的解除分配(即数组只被删除?)
所以我想我的问题是,析构函数只是delete在对象上调用时调用的另一个函数,还是它做了更多?
tem*_*def 30
如果你写
fool->~Fool();
Run Code Online (Sandbox Code Playgroud)
您结束对象的生命周期,它会调用析构函数并回收内部array数组.但是,没有释放持有对象的内存,这意味着如果您想使用placement new将对象恢复生命:
new (fool) Fool;
Run Code Online (Sandbox Code Playgroud)
你可以这样做.
根据规范,fool在显式调用析构函数之后读取或写入字段的值会导致未定义的行为,因为对象的生命周期已经结束,但是仍然应该分配持有该对象的内存,并且您需要通过调用来释放它operator delete:
fool->~Fool();
operator delete(fool);
Run Code Online (Sandbox Code Playgroud)
使用的原因operator delete而不仅仅是写作
delete fool;
Run Code Online (Sandbox Code Playgroud)
是后者有不确定的行为,因为它fool的生命已经结束.使用原始释放例程operator delete可确保回收内存,而无需尝试执行任何操作来结束对象的生命周期.
当然,如果对象的内存不是来自new(可能是堆栈分配,或者您可能正在使用自定义分配器),那么您不应该使用operator delete它来释放它.如果你这样做了,你最终会得到未定义的行为(再次!).这似乎是这个问题中反复出现的主题.:-)
希望这可以帮助!
析构函数调用就是这样,它调用析构函数.没有更多,也没有更少.分配与构造分开,并从破坏中解除分配.
典型的顺序是这样的:
1. Allocate memory
2. Construct object
3. Destroy object (assuming no exception during construction)
4. Deallocate memory
Run Code Online (Sandbox Code Playgroud)
实际上,如果你手动运行它,你将不得不自己调用析构函数:
void * addr = ::operator new(sizeof(Fool));
Fool * fp = new (addr) Fool;
fp->~Fool();
::operator delete(addr);
Run Code Online (Sandbox Code Playgroud)
写这个的自动方式当然是Fool * fp = new Fool; delete fp;.该new表达式调用分配和建设为你和delete表达调用析构函数并释放内存.