Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Using smart pointers with Boost.Intrusive containers 讓 Boost.Intrusive 容器使用智能指針

Requirements for smart pointers compatible with Boost.Intrusive 兼容於 Boost.Intrusive 的智能指針的要求

Boost.Intrusive hooks can be configured to use other pointers than raw pointers. When a Boost.Intrusive hook is configured with a smart pointer as an argument, this pointer configuration is passed to the containers. For example, if the following hook is configured with a smart pointer (for example, an offset pointer from Boost.Interprocess):
Boost.Intrusive 鉤子可以被配置為使用裸指針以外的其它指針。當一個 Boost.Intrusive 鉤子被用智能指針作為參數來配置時,該指針的配置會被傳遞到容器。例如,如果以下鉤子是用智能指針(如 Boost.Interprocess 的偏移量指針)來配置的:

#include <boost/intrusive/list.hpp>
#include <boost/interprocess/offset_ptr.hpp>

using namespace boost::intrusive;
namespace ip = boost::interprocess;

class shared_memory_data
   //Declare the hook with an offset_ptr from Boost.Interprocess
//to make this class compatible with shared memory
//聲明帶有一個 Boost.Interprocess 的 offser_ptr 的鉤子,使得這個類兼容於共享內存
: public list_base_hook< void_pointer< ip::offset_ptr<void> > > { int data_id_; public: int get() const { return data_id_; } void set(int id) { data_id_ = id; } };

Any intrusive list constructed using this hook will be ready for shared memory, because the intrusive list will also use offset pointers internally. For example, we can create an intrusive list in shared memory combining Boost.Interprocess and Boost.Intrusive:
任何用這個鉤子構造的介入式鏈表都可以使用共享內存,因為介入式鏈表內部也是使用偏移量指針。例如,我們可以結合 Boost.InterprocessBoost.Intrusive 在共享內存中創建一個介入式鏈表:

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/containers/list.hpp>
#include <boost/interprocess/allocators/allocator.hpp>

//Definition of the shared memory friendly intrusive list 可使用共享內存的介入式鏈表的定義
typedef ip::list<shared_memory_data> shm_list_t; int main() { //Now create an intrusive list in shared memory: 現在在共享內存中創建一個介入式鏈表
//nodes and the container itself must be created in shared memory 節點與容器本身都必須在共享內存中創建
const int MaxElem = 100; const int ShmSize = 50000; const char *ShmName = get_shared_memory_name(); { //Erase all old shared memory 刪除所有舊的共享內存
ip::shared_memory_object::remove(ShmName); ip::managed_shared_memory shm(ip::create_only, ShmName, ShmSize); //Create all nodes in shared memory using a shared memory vector
//See Boost.Interprocess documentation for more information on this
//使用一個共享內存 vector 在共享內存中創建所有節點。有關於此的更多信息請見 Boost.Interprocess
typedef ip::allocator < shared_memory_data, ip::managed_shared_memory::segment_manager> shm_allocator_t; typedef ip::vector<shared_memory_data, shm_allocator_t> shm_vector_t; shm_allocator_t shm_alloc(shm.get_segment_manager()); shm_vector_t *pshm_vect =
shm.construct<shm_vector_t>(ip::anonymous_instance)(shm_alloc); pshm_vect->resize(MaxElem); //Initialize all the nodes 初始化所有節點
for(int i = 0; i < MaxElem; ++i) (*pshm_vect)[i].set(i); //Now create the shared memory intrusive list 現在創建一個共享內存介入式鏈表
shm_list_t *plist = shm.construct<shm_list_t>(ip::anonymous_instance)(); plist->insert(plist->end(), pshm_vect->begin(), pshm_vect->end()); //Check all the inserted nodes 檢查所有插入的節點
int checker = 0; for( shm_list_t::const_iterator it = plist->begin(), itend(plist->end()) ; it != itend; ++it, ++checker){ if(it->get() != checker) return false; } //Now delete the list and after that, the nodes 現在銷毀鏈表及節點
shm.destroy_ptr(plist); shm.destroy_ptr(pshm_vect); } ip::shared_memory_object::remove(ShmName); return 0; }

Not every smart pointer is compatible with Boost.Intrusive; the smart pointer must have the following features:
不同每個智能指針都能兼容於 Boost.Intrusive;智能指針必須具有以下特點:

  • It must support the same operations as a raw pointer, except casting.
    它必須支持和裸指針一樣的操作,除了轉型。
  • It must be convertible to a raw pointer and constructible from a raw pointer.
    它必須可以轉型為裸指針,以及可以從裸指針構造。
  • It must have the same ownership semantics as a raw pointer. This means that resource management smart pointers (like boost::shared_ptr) can't be used.
    它必須具有與裸指針相同的擁有權語義。即資源管理類的智能指針(如 boost::shared_ptr)不可使用。

The conversion from the smart pointer to a raw pointer must be implemented following Boost smart pointer detail::get_pointer() function. This function will be found using ADL. For example, for boost::interprocess::offset_ptr, detail::get_pointer is defined as follows:
從智能指針到裸指針的轉換必須實現為以下 Boost 智能指針 detail::get_pointer() 函數。該函數將通過 ADL 被發現。例如,對於 boost::interprocess::offset_ptr, detail::get_pointer,定義如下:

template<class T>
T * detail::get_pointer(boost::interprocess::offset_ptr<T> const & p)
{  return p.get();   }

PrevUpHomeNext