2.8. 介入式指针
大体上,介入式指针的工作方式和共享指针完全一样。 boost::shared_ptr
在内部记录着引用到某个对象的共享指针的数量,可是对介入式指针来说,程序员就得自己来做记录。 对于框架对象来说这就特别有用,因为它们记录着自身被引用的次数。
介入式指针 boost::intrusive_ptr
定义在 boost/intrusive_ptr.hpp
里。
- #include <boost/intrusive_ptr.hpp>
- #include <atlbase.h>
- #include <iostream>
- void intrusive_ptr_add_ref(IDispatch *p)
- {
- p->AddRef();
- }
- void intrusive_ptr_release(IDispatch *p)
- {
- p->Release();
- }
- void check_windows_folder()
- {
- CLSID clsid;
- CLSIDFromProgID(CComBSTR("Scripting.FileSystemObject"), &clsid);
- void *p;
- CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, __uuidof(IDispatch), &p);
- boost::intrusive_ptr<IDispatch> disp(static_cast<IDispatch*>(p));
- CComDispatchDriver dd(disp.get());
- CComVariant arg("C:\\Windows");
- CComVariant ret(false);
- dd.Invoke1(CComBSTR("FolderExists"), &arg, &ret);
- std::cout << (ret.boolVal != 0) << std::endl;
- }
- void main()
- {
- CoInitialize(0);
- check_windows_folder();
- CoUninitialize();
- }
上面的例子中使用了 COM(组件对象模型)提供的函数,于是乎只能在 Windows 平台上编译运行。 COM 对象是使用 boost::intrusive_ptr
的绝佳范例,因为 COM 对象需要记录当前有多少指针引用着它。 通过调用 AddRef()
和 Release()
函数,内部的引用计数分别增 1 或者减 1。当引用计数为 0 时,COM 对象自动销毁。
在 intrusiveptr_add_ref()
和 intrusive_ptr_release()
内部调用 AddRef()
和 Release()
这两个函数,来增加或减少相应 COM 对象的引用计数。 这个例子中用到的 COM 对象名为 'FileSystemObject',在 Windows 上它是默认可用的。通过这个对象可以访问底层的文件系统,比如检查一个给定的目录是否存在。 在上例中,我们检查 C:\Windows
目录是否存在。 具体它在内部是怎么实现的,跟 boost::intrusive_ptr
的功能无关,完全取决于 COM。 关键点在于一旦介入式指针 _disp 离开了它的作用域——check_windows_folder()
函数的末尾,函数 intrusive_ptr_release()
将会被自动调用。 这将减少 COM 对象 'FileSystemObject' 的内部引用计数到0,于是该对象就销毁了。