孟岩在自己的blog上
提到了 Scott Meyers在Artima.com的C++ Source栏目中发表的一个5×5的系列。其中最后一篇是Scott Meyers的
五个最重要的C++Aha!时刻 ,孟岩提示大家关注最后一个。如果关注过Scott Meyers和他的Effectiv系列的话,对他前四个Aha!时刻应该都已经熟识了。
这里仅翻译第五个:
明白Boost的shared_ptr里deleter是如何工作的,2004
Boost的引用计数智能指针shared_ptr有一个有趣的特性,你可以传入一个函数或者一个函数体,并且当引
用计数为零时,它会对指向的对象调用这个deleter。让人脸红的是,这看起来很平凡,但是请看这段代码:
template<typename T>
class shared_ptr {
public:
template<typename U, typename D>
explicit shared_ptr(U* ptr, D deleter);
![](/Images/dot.gif)
};
要注意的是在析构的期间shared_ptr<T>必须为类型为D的deleter做些安排,以确保它的调用,然而shared_ptr<T>并不知道类型D到底是什么。此对象不能包含类型为D的数据成员,当然也不能有一个指向类型为D的对象的指针,因为当对象成员数据声明的时候对于D好不知情。那么shared_ptr对象如何在构造期deleter被传入时保存它的踪迹,并且在稍后的析构期使用它的呐?更一般的说法,在一个对象的构造期间构造函数如何获得未知类型的信息,并把类型的信息传给此对象,而对象不能保存关于此类型任何提示。
答案很简单:此对象包含一个已知类型的基类指针(Boost管它叫做 sp_counted_base ),指向一个已经构造实例化的模板,此模板继承自前面的基类,并使用D作为实例化参数(Boost使用模板 sp_counted_impl_p 和 sp_counted_impl_pd ),使用一个在基类里声明,继承类中定义的虚函数来调用 deleter (Boost使用 dispose )。稍微简化了,它看起来像下面这样:
它是很明显的,只要你看过它一次。但是只要你看过它一次,你就会体会到它可以被用到很多种类的地方,它打开了模板设计的新视野,模板化类使用相对较少的模板参数(shared_ptr 只是其中一个)可以引用不受数量限制的当前不知名类型的信息。当我意识到我接近的东西,我不能禁止地露出赞赏的笑容并摇晃我的脑袋。
posted on 2006-11-03 01:10
小山日志 阅读(745)
评论(0) 编辑 收藏 引用 所属分类:
stl/boost/loki/generically