避免使用终结函数

 

至少到现在我还没有显式的调用过系统的终结函数。在JLS中提到:终结函数不能保证被及时执行;甚至它有可能不执行。因此,时间关键的任务不应该由终结函数来完成。

我们要做的最好是提供一个显式的终止方法,并要求该类的客户在每个实例不再有用的时候调用这个方法。例如关闭数据库以及关闭InputStreamOutputStream.close()方法等,这些方法可以和try…finally结构结合起来使用,以确保及时终止释放资源。

终结函数还是有合理用途的:

  1. 当一个对象的所有者忘记了调用上面提到的显式终止方法的情况下,终结函数可以充当“安全网”。虽然这不能保证终结函数被及时的调用到,但是,至少迟一些调用释放资源总比不释放要好。
  2. 第二个合理用途是与本地的对等体(native peer)有关。本地对等体是一个本地对象,普通对象通过本地方法委托给一个本地对象,因为本地对等体不是一个普通对象,所以垃圾回收器不会知道它,当它的普通对等体被回收的时候,它不会被回收。在本地对等体并不拥有关键资源的前提下,终结函数正是执行这项任务最合适的工具

需要注意一点,“终结函数链”不会被自动执行。也就是说,如果一个类(不是Object)有一个终结函数,并且一个子类改写了终结函数,那么子类的终结函数必须要用手工调用超类的终结函数。

 
### C++ 析构函数的继承规则 #### 析构函数的作用与概念 析构函数用于释放对象占用的资源,确保程序结束时能够清理不再使用的内存和其他资源。对于派生类而言,在其生命周期结束时不仅需要销毁自身的成员变量,还需要调用基类的析构函数来完成整个层次结构内的资源回收工作。 #### 默认行为下的析构过程 当一个派生类的对象被销毁时,编译器会按照特定顺序依次调用该对象所属类型的各个级别的析构方法: - 首先执行最底层(即派生程度最高)的具体类别的析构逻辑; - 接着逐层向上直到顶层父级类别,每上升一层都会相应地触发对应级别上的析构动作; 这种机制保证了即使程序员未手动编写任何额外代码的情况下也能安全有效地清除所有关联的数据项[^1]。 #### 虚析构函数的重要性 为了使上述流程更加灵活可控,建议将基类声明为具有虚拟性的析构子程 (virtual destructor),这样可以确保通过指针或引用删除多态类型实例时能正确调用到实际运行时刻所指向的确切版本的终结处理例程[^3]。 ```cpp class Base { public: virtual ~Base() {} // 宣告虚析构函数 }; class Derived : public Base { public: ~Derived(); // 自动成为虚函数,无需再次使用关键字virtual }; ``` #### 显式调用基类析构的情况 一般情况下不推荐也不必显式调用基类的析构函数,除非有特殊需求要在某些自定义操作前后精确控制基类部分的状态变化。此时可以在派生类的析构实现内部适当位置加入`base_class_name::~base_class_name()`这样的语句来进行针对性干预。 #### 错误示范:在析构期间访问虚表成员 应当避免尝试于此类场景下调用可能涉及动态绑定特性的接口成员,因为随着当前作用域即将关闭,那些依赖于完整上下文环境才能正常工作的功能很可能已经失效或者处于不稳定状态之中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值