自由存储
命名对象的生存时间由它的作用域(4.9.4节)决定。然而,能够建立起生存时间不依赖于建立它作用域的对象,这件事情也是很有用的。特别地,人们经常要建立起一些对象,希望在建立它们的函数返回之后还能够使用它们。运算符new将建立起这种对象,而运算符delete能用于销毁它们。由new分配的对象被说成是在“自由存储里的”(也说是“堆对象”或者“在动态存储中分配的”)。
现在考虑我们可能如何按照写桌面计算器(6.1节)的方式写一个编辑器。语法分析函数可能去构造一个为代码生成器而用的表达式树
struct Enode {
Toekn_value oper;
Enode* left;
Enode* right;
// ...
};
Enode* expr(bool get)
{
Enode* left = term(get);
for(;;)
switch(curr_tok){
case PLUS:
case MINUS:
{
Enode* n = new Enode; // 在自由存储里建立一个Enode
n->oper = curr_tok;
n->left = left;
n->right = term(true);
left = n;
break;
}
default:
return left; // 返回节点
}
}
代码生成器在此之后使用这些节点,而后销毁它们
void generate(Enode* n)
{
switch(n->open){
case PLUS:
// ...
delete n; // 删除来自自由存储的Enode
}
}
由new创建的对象将一只存在,直到它被用delete显式地销毁为止。在此之后,由它所占用的存储就又能被new使用了。C++实现并不保证提供一个“废料收集器”,由它去找回不再存在的引用的对象并使它们占用的存储重新可以被new使用。因此,我将一只假定所有通过new建立的对象都需要手工地用delete释放。如果系统里提供了废料收集器,那么在大部分情况下的delete都可以省去(C.9.1节)。
delete运算符只能用到由new返回的指针或者0,对0应用不会造成任何影响。
还可以定义运算符new的特定版本(15.6节)。
🔚