码迷,mamicode.com
首页 > 其他好文 > 详细

不要让继承自引用计数管理资源的对象在栈上实例

时间:2017-10-13 18:03:30      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:虚函数   资源   计数   操作   对象   大致   art   例子   red   

引用计数进行管理资源,我们最熟悉的就是智能指针。在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就小心了。

不要让继承自引用计数管理资源的对象在栈上实例

标签:虚函数   资源   计数   操作   对象   大致   art   例子   red   

原文地址:http://www.cnblogs.com/bbqzsl/p/7662164.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!