zoukankan      html  css  js  c++  java
  • 不要让继承自引用计数管理资源的对象在栈上实例

    引用计数进行管理资源,我们最熟悉的就是智能指针。在c++11之前,我们的对象都从一个引用计数管理资源的类继承,这个类有一个引用计数器,两个配对的操作addref和delref,当delref将引用计数器减为0时,会自动调用delete。这种机制要求对象必须实例在堆上,也就是new创建。当决定继承一个对象时,你必须小心看一遍它的继承树,是否继承了这一种的类。

    一旦你将使用引用计数管理资源的对象在栈上实例后,这个对象就有可能被栈和堆同时管理资源。首先在栈实例后,这个对象一定会在栈帧作用域内被管理资源,当离开栈帧时对象被释放。如果有一个函数很深层调用,或这个对象的某个接口函数将这个对象的指针送进了智能指针,这时就带来灾难了,这个对象又被堆管理上资源了。当这个意外的智能指针销毁时,这个栈上对象却用堆来管理资源了。或者这个意外的智能指针保留了一个野指针,栈对象已经离开作用域。

    IceUtil::Thread就是一个例子。在主线程的栈上实例这些继承来的线程对象,然后开始这些线程,在主线程退出前停止这些线程,线程对象离开局部作用域对象被栈回收。但问题来了,IceUtil::Thread is a IceUtil::Shared,这个IceUtil::Shared就是一个引用计数管理资源的类。IceUtil::Thread::start(),这个接口在开始一个线程时,将线程对象以智能指针方式作为线程参数了,换句话说这个智能指针生命期与新线程相随。当主线程栈上的线程对象停止线程时,线程在退出时线程对象因为智能指针而被delete,灾难发生了。

    boost::thread,IceUtil::Thread或其它框架库都有封装线程类,大家的设计的思想大致也都为重写run虚函数,start启动线程,stop停止线程。但是使用上细节不是全盘通用的。boost::thread可以在栈上实例,但IceUtil::Thread就小心了。

  • 相关阅读:
    浅拷贝与深拷贝
    Hibernate入门(1)-第一个Hibernate程序
    Spring入门(10)-Spring JDBC
    【Java,IDEA】创建自己的代码模版快速生成
    【Java,IDEA】使用IDEA自动生成序列化ID
    【Project】原生JavaWeb工程 02 登陆业务的流程(第一阶段样例)
    【AJAX】Asynchronous JavaScript And XML (非同步的JS & XML)
    【JS】06 语法补充
    【JS】05 DOM 文档对象模型 P2 元素的CRUD、Dom集合对象
    【JS】04 DOM 文档对象模型 P1 查找元素、改变内容、绑定事件
  • 原文地址:https://www.cnblogs.com/bbqzsl/p/7662164.html
Copyright © 2011-2022 走看看