Boost.Interprocess使用手册翻译之十一:所有权的智能指针(Ownership smart pointers)

十一.所有权的智能指针

浸入式指针(Intrusive pointer)

作用域指针(Scoped pointer)

共享指针和弱指针(Shared pointer and weak pointer)

唯一指针(Unique pointer)

当处理资源时,C++使用者知道所有权智能指针的重要性。Boost提供了广泛的这些类型的指针:intrusive_ptr<>, scoped_ptr<>,shared_ptr<>...

当构建复杂的共享内存/内存映射文件结构时,程序员可能会想使用这些智能指针的优势。问题是Boost和C++TR1智能指针并不能在共享内存中使用。原因是这些指针包含了原始指针并且使用了虚函数,因此如果你想在共享内存中放置数据,那是不可能的。虚函数限制使甚至使用Boost.Interprocess智能指针也不能获得相同等级的Boost和TR1功能。

进程间所有权智能指针主要是“包含智能指针的智能指针”,因此我们能够指定它们包含的指针类型。

浸入式指针

boost::interprocess::intrusive_ptr 是 boost::intrusive_ptr<>的泛化,它允许非原始指针做为浸入式指针的成员。对于著名的boost::intrusive_ptr ,我们必须指定指针对象类型,但是我们也必须指定存储在intrusive_ptr中的指针类型:

   
   
  1. //!The intrusive_ptr class template stores a pointer to an object  
  2. //!with an embedded reference count. intrusive_ptr is parameterized on  
  3. //!T (the type of the object pointed to) and VoidPointer(a void pointer type   
  4. //!that defines the type of pointer that intrusive_ptr will store).  
  5. //!intrusive_ptr<T, void *> defines a class with a T* member whereas  
  6. //!intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member.  
  7. //!Relies on unqualified calls to:  
  8. //!   
  9. //!void intrusive_ptr_add_ref(T * p);  
  10. //!void intrusive_ptr_release(T * p);  
  11. //!  
  12. //!with (p != 0)  
  13. //!  
  14. //!The object is responsible for destroying itself.  
  15. template<class T, class VoidPointer>  
  16. class intrusive_ptr;  

因此boost::interprocess::intrusive_ptr<MyClass, void*>与boost::intrusive_ptr<MyClass>等价。但如果我们想在共享内存中放置intrusive_ptr,我们必须指定一个相对指针类型,比如boost::interprocess::intrusive_ptr<MyClass, boost::interprocess::offset_ptr<void> >

   
   
  1. #include <boost/interprocess/managed_shared_memory.hpp>  
  2. #include <boost/interprocess/smart_ptr/intrusive_ptr.hpp>  
  3.    
  4. using namespace boost::interprocess;  
  5.    
  6. namespace N {  
  7.    
  8. //A class that has an internal reference count  
  9. class reference_counted_class  
  10. {  
  11.    private:  
  12.    //Non-copyable  
  13.    reference_counted_class(const reference_counted_class  &);  
  14.    //Non-assignable  
  15.    reference_counted_class & operator=(const reference_counted_class &);  
  16.    //A typedef to save typing  
  17.    typedef managed_shared_memory::segment_manager segment_manager;  
  18.    //This is the reference count  
  19.    unsigned int m_use_count;  
  20.    //The segment manager allows deletion from shared memory segment  
  21.    offset_ptr<segment_manager> mp_segment_manager;  
  22.    
  23.    public:  
  24.    //Constructor  
  25.    reference_counted_class(segment_manager *s_mngr)  
  26.    : m_use_count(0), mp_segment_manager(s_mngr){}  
  27.    //Destructor  
  28.    ~reference_counted_class(){}  
  29.    
  30.    public:  
  31.    //Returns the reference count  
  32.    unsigned int use_count() const  
  33.    {  return m_use_count;   }  
  34.    
  35.    //Adds a reference  
  36.    inline friend void intrusive_ptr_add_ref(reference_counted_class * p)  
  37.    {  ++p->m_use_count; }  
  38.    
  39.    //Releases a reference  
  40.    inline friend void intrusive_ptr_release(reference_counted_class * p)  
  41.    {  if(--p->m_use_count == 0)  p->mp_segment_manager->destroy_ptr(p); }  
  42. };  
  43.    
  44. }  //namespace N {  
  45.    
  46. //A class that has an intrusive pointer to reference_counted_class  
  47. class intrusive_ptr_owner  
  48. {  
  49.    typedef intrusive_ptr<N::reference_counted_class,  
  50.                            offset_ptr<void> > intrusive_ptr_t;  
  51.    intrusive_ptr_t m_intrusive_ptr;  
  52.    
  53.    public:  
  54.    //Takes a pointer to the reference counted class  
  55.    intrusive_ptr_owner(N::reference_counted_class *ptr)  
  56.       : m_intrusive_ptr(ptr){}  
  57. };  
  58.    
  59. int main()  
  60. {  
  61.    //Remove shared memory on construction and destruction  
  62.    struct shm_remove  
  63.    {  
  64.       shm_remove() { shared_memory_object::remove("MySharedMemory"); }  
  65.       ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }  
  66.    } remover;  
  67.    
  68.    //Create shared memory  
  69.    managed_shared_memory shmem(create_only, "MySharedMemory", 10000);  
  70.    
  71.    //Create the unique reference counted object in shared memory  
  72.    N::reference_counted_class *ref_counted =  
  73.       shmem.construct<N::reference_counted_class>  
  74.          ("ref_counted")(shmem.get_segment_manager());  
  75.    
  76.    //Create an array of ten intrusive pointer owners in shared memory  
  77.    intrusive_ptr_owner *intrusive_owner_array =  
  78.       shmem.construct<intrusive_ptr_owner>  
  79.          (anonymous_instance)[10](ref_counted);  
  80.    
  81.    //Now test that reference count is ten  
  82.    if(ref_counted->use_count() != 10)  
  83.       return 1;  
  84.    
  85.    //Now destroy the array of intrusive pointer owners  
  86.    //This should destroy every intrusive_ptr and because of  
  87.    //that reference_counted_class will be destroyed  
  88.    shmem.destroy_ptr(intrusive_owner_array);  
  89.    
  90.    //Now the reference counted object should have been destroyed  
  91.    if(shmem.find<intrusive_ptr_owner>("ref_counted").first)  
  92.       return 1;  
  93.    //Success!  
  94.    return 0;  
  95. }  

作用域指针

boost::interprocess::scoped_ptr<>是boost::scoped_ptr<>的大哥,它增加了一个定制的删除器用于指定如何销毁传入至scoped_ptr的指针。并且,删除器的指针类型定义也将指定被scoped_ptr存储的指针类型。

   
   
  1. //!scoped_ptr stores a pointer to a dynamically allocated object.   
  2. //!The object pointed to is guaranteed to be deleted, either on destruction  
  3. //!of the scoped_ptr, or via an explicit reset. The user can avoid this  
  4. //!deletion using release().  
  5. //!scoped_ptr is parameterized on T (the type of the object pointed to) and   
  6. //!Deleter (the functor to be executed to delete the internal pointer).  
  7. //!The internal pointer will be of the same pointer type as typename   
  8. //!Deleter::pointer type (that is, if typename Deleter::pointer is   
  9. //!offset_ptr<void>, the internal pointer will be offset_ptr<T>).  
  10. template<class T, class Deleter>  
  11. class scoped_ptr;  

scoped_ptr<>在执行异常回滚时是得心应手的:如果抛出异常或我们在scoped_ptr<>作用域内调用了return,删除器将自动调用以便删除器能被认为是一个回滚函数。如果一切顺利,当scoped_ptr超出作用域时,我们调用release()成员函数来避免回滚。

   
   
  1. #include <boost/interprocess/managed_shared_memory.hpp>  
  2. #include <boost/interprocess/smart_ptr/scoped_ptr.hpp>  
  3.    
  4. using namespace boost::interprocess;  
  5.    
  6. class my_class  
  7. {};  
  8.    
  9. class my_exception  
  10. {};  
  11.    
  12. //A functor that destroys the shared memory object  
  13. template<class T>  
  14. class my_deleter  
  15. {  
  16.    private:  
  17.    //A typedef to save typing  
  18.    typedef managed_shared_memory::segment_manager segment_manager;  
  19.    //This my_deleter is created in the stack, not in shared memory,  
  20.    //so we can use raw pointers  
  21.    segment_manager *mp_segment_manager;  
  22.    
  23.    public:  
  24.    //This typedef will specify the pointer type that  
  25.    //scoped_ptr will store  
  26.    typedef T *pointer;  
  27.    //Constructor  
  28.    my_deleter(segment_manager *s_mngr)  
  29.    : mp_segment_manager(s_mngr){}  
  30.    
  31.    void operator()(pointer object_to_delete)  
  32.    {  mp_segment_manager->destroy_ptr(object_to_delete);  }  
  33. };  
  34.    
  35. int main ()  
  36. {  
  37.    //Create shared memory  
  38.    //Remove shared memory on construction and destruction  
  39.    struct shm_remove  
  40.    {  
  41.       shm_remove() { shared_memory_object::remove("MySharedMemory"); }  
  42.       ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }  
  43.    } remover;  
  44.    
  45.    managed_shared_memory shmem(create_only, "MySharedMemory", 10000);  
  46.    
  47.    //In the first try, there will be no exceptions  
  48.    //in the second try we will throw an exception  
  49.    for(int i = 0; i < 2; ++i){  
  50.       //Create an object in shared memory  
  51.       my_class * my_object = shmem.construct<my_class>("my_object")();  
  52.       my_class * my_object2 = shmem.construct<my_class>(anonymous_instance)();  
  53.       shmem.destroy_ptr(my_object2);  
  54.    
  55.       //Since the next shared memory allocation can throw  
  56.       //assign it to a scoped_ptr so that if an exception occurs  
  57.       //we destroy the object automatically  
  58.       my_deleter<my_class> d(shmem.get_segment_manager());  
  59.    
  60.       try{  
  61.          scoped_ptr<my_class, my_deleter<my_class> > s_ptr(my_object, d);  
  62.          //Let's emulate a exception capable operation  
  63.          //In the second try, throw an exception  
  64.          if(i == 1){  
  65.             throw(my_exception());  
  66.          }  
  67.          //If we have passed the dangerous zone  
  68.          //we can release the scoped pointer  
  69.          //to avoid destruction  
  70.          s_ptr.release();  
  71.       }  
  72.       catch(const my_exception &){}  
  73.       //Here, scoped_ptr is destroyed  
  74.       //so it we haven't thrown an exception  
  75.       //the object should be there, otherwise, destroyed  
  76.       if(i == 0){  
  77.          //Make sure the object is alive  
  78.          if(!shmem.find<my_class>("my_object").first){  
  79.             return 1;  
  80.          }  
  81.          //Now we can use it and delete it manually  
  82.          shmem.destroy<my_class>("my_object");  
  83.       }  
  84.       else{  
  85.          //Make sure the object has been deleted  
  86.          if(shmem.find<my_class>("my_object").first){  
  87.             return 1;  
  88.          }  
  89.       }  
  90.    }  
  91.    return 0;  
  92. }  

共享指针和弱指针

Boost.Interprocess也提供了在托管共享内存或映射文件中创建非浸入式引用计数(non-intrusive reference-counted)对象的可能性。

与boost::shared_ptr不同,由于映射片段的限制,当提供用户自定义的分配器和删除器时boost::interprocess::shared_ptr不能使用虚函数来维护同样的共享指针类型。分配器和删除器是共享指针的模板参数。

由于引用计数和其他shared_ptr 需要的辅助数据也必须在托管内存片段中被创建,并且删除器必须从片段中删除对象,因此当构建一个非空的shared_ptr 实例时,用户必须指定一个分配器对象和删除器对象,就好像Boost.Interprocess容器需要在它们构造函数中传入分配器一样。

下面是shared_ptr的声明:

   
   
  1. template<class T, class VoidAllocator, class Deleter>  
  2. class shared_ptr;  
  • T是指向的类型的类型。
  • VoidAllocator是用来分配辅助成员例如引用计数、删除器等的分配器。分配器的内部指针类型定义将决定shared_ptr内部使用的指针类型,因此分配器定义指针offset_ptr<void>将使得所有shared_ptr使用的内部指针也是相对指针。参考boost::interprocess::allocator以获取工作分配器的详细信息。
  • Deleter是函数对象,当对对象的最后一个引用被销毁后,它被用来销毁指向的对象。删除器函数将使用一个与VoidAllocator::pointer定义的空指针一样的T指针。参考boost::interprocess::deleter 以获取从一个托管内存片段上删除一个对象的通常的删除器的详细信息。

采用正确指定的参数,Boost.Interprocess用户能够创建对象在共享内存中,它承载了指向此共享内存中其他对象的共享指针,获得引用计数的好处。让我们看看如何在一个托管共享内存中创建一个共享指针:

   
   
  1. #include <boost/interprocess/managed_shared_memory.hpp>  
  2. #include <boost/interprocess/smart_ptr/shared_ptr.hpp>  
  3. #include <boost/interprocess/allocators/allocator.hpp>  
  4. #include <boost/interprocess/smart_ptr/deleter.hpp>  
  5. #include <cassert>  
  6.    
  7. using namespace boost::interprocess;  
  8.    
  9. //This is type of the object we want to share  
  10. class MyType  
  11. {};  
  12.    
  13. typedef managed_shared_memory::segment_manager segment_manager_type;  
  14. typedef allocator<void, segment_manager_type>  void_allocator_type;  
  15. typedef deleter<MyType, segment_manager_type>  deleter_type;  
  16. typedef shared_ptr<MyType, void_allocator_type, deleter_type> my_shared_ptr;  
  17.    
  18. int main ()  
  19. {  
  20.    //Remove shared memory on construction and destruction  
  21.    struct shm_remove  
  22.    {  
  23.       shm_remove() { shared_memory_object::remove("MySharedMemory"); }  
  24.       ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }  
  25.    } remover;  
  26.    
  27.    managed_shared_memory segment(create_only, "MySharedMemory", 4096);  
  28.    
  29.    //Create a shared pointer in shared memory  
  30.    //pointing to a newly created object in the segment  
  31.    my_shared_ptr &shared_ptr_instance =  
  32.       *segment.construct<my_shared_ptr>("shared ptr")  
  33.          //Arguments to construct the shared pointer  
  34.          ( segment.construct<MyType>("object to share")()      //object to own  
  35.          , void_allocator_type(segment.get_segment_manager())  //allocator  
  36.          , deleter_type(segment.get_segment_manager())         //deleter  
  37.          );  
  38.    assert(shared_ptr_instance.use_count() == 1);  
  39.    
  40.    //Destroy "shared ptr". "object to share" will be automatically destroyed  
  41.    segment.destroy_ptr(&shared_ptr_instance);  
  42.    
  43.    return 0;  
  44. }  

boost::interprocess::shared_ptr是非常弹性和可配置的(例如,我们能指定分配器和删除器),但是如上示,在托管内存片段上创建共享指针需要太多代码了。

为简化使用,boost::interprocess::shared_ptr头文件提供了一个共享指针定义帮助类(managed_shared_ptr)和一个函数(make_managed_shared_ptr)来简化从一个分配在托管内存片段上的类型构建一个共享指针,它带一个在托管内存片段上分配引用计数的分配器和一个从片段中删除对象的删除器。

这些工具将使用Boost.Interprocess分配器(boost::interprocess::allocator)和删除器(boost::interprocess::deleter)来做它们的工作。之前的共享指针定义能够被简化成如下:

   
   
  1. typedef managed_shared_ptr<MyType, managed_shared_memory>::type my_shared_ptr;  

并且共享指针的创建能够简化为:

   
   
  1. my_shared_ptr sh_ptr = make_managed_shared_ptr  
  2.    (segment.construct<MyType>("object to share")(), segment);  

Boost.Interprocess也提供了一个弱指针名为weak_ptr (它相对应的工具为 managed_weak_ptr和make_managed_weak_ptr)来对shared_ptr拥有的对象执行非所属观察。

现在,让我们看看一个使用shared_ptr和weak_ptr的详细例子:

   
   
  1. #include <boost/interprocess/managed_mapped_file.hpp>  
  2. #include <boost/interprocess/smart_ptr/shared_ptr.hpp>  
  3. #include <boost/interprocess/smart_ptr/weak_ptr.hpp>  
  4. #include <cassert>  
  5.    
  6. using namespace boost::interprocess;  
  7.    
  8. //This is type of the object we want to share  
  9. struct type_to_share  
  10. {};  
  11.    
  12. //This is the type of a shared pointer to the previous type  
  13. //that will be built in the mapped file  
  14. typedef managed_shared_ptr<type_to_share, managed_mapped_file>::type shared_ptr_type;  
  15. typedef managed_weak_ptr<type_to_share, managed_mapped_file>::type   weak_ptr_type;  
  16.    
  17. //This is a type holding a shared pointer  
  18. struct shared_ptr_owner  
  19. {  
  20.    shared_ptr_owner(const shared_ptr_type &other_shared_ptr)  
  21.       : shared_ptr_(other_shared_ptr)  
  22.    {}  
  23.    
  24.    shared_ptr_owner(const shared_ptr_owner &other_owner)  
  25.       : shared_ptr_(other_owner.shared_ptr_)  
  26.    {}  
  27.    
  28.    shared_ptr_type shared_ptr_;  
  29.    //...  
  30. };  
  31.    
  32. int main ()  
  33. {  
  34.    //Define file names  
  35.    const char *MappedFile  = "MyMappedFile";  
  36.    
  37.    //Destroy any previous file with the name to be used.  
  38.    struct file_remove  
  39.    {  
  40.       file_remove(const char *MappedFile)  
  41.          : MappedFile_(MappedFile) { file_mapping::remove(MappedFile_); }  
  42.       ~file_remove(){ file_mapping::remove(MappedFile_); }  
  43.       const char *MappedFile_;  
  44.    } remover(MappedFile);  
  45.    {  
  46.       managed_mapped_file file(create_only, MappedFile, 65536);  
  47.    
  48.       //Construct the shared type in the file and  
  49.       //pass ownership to this local shared pointer  
  50.       shared_ptr_type local_shared_ptr = make_managed_shared_ptr  
  51.          (file.construct<type_to_share>("object to share")(), file);  
  52.       assert(local_shared_ptr.use_count() == 1);  
  53.    
  54.       //Share ownership of the object between local_shared_ptr and a new "owner1"  
  55.       shared_ptr_owner *owner1 =  
  56.          file.construct<shared_ptr_owner>("owner1")(local_shared_ptr);  
  57.       assert(local_shared_ptr.use_count() == 2);  
  58.    
  59.       //local_shared_ptr releases object ownership  
  60.       local_shared_ptr.reset();  
  61.       assert(local_shared_ptr.use_count() == 0);  
  62.       assert(owner1->shared_ptr_.use_count() == 1);  
  63.    
  64.       //Share ownership of the object between "owner1" and a new "owner2"  
  65.       shared_ptr_owner *owner2 =  
  66.          file.construct<shared_ptr_owner>("owner2")(*owner1);  
  67.       assert(owner1->shared_ptr_.use_count() == 2);  
  68.       assert(owner2->shared_ptr_.use_count() == 2);  
  69.       assert(owner1->shared_ptr_.get() == owner2->shared_ptr_.get());  
  70.    
  71.       //The mapped file is unmapped here. Objects have been flushed to disk  
  72.    }  
  73.    {  
  74.       //Reopen the mapped file and find again all owners  
  75.       managed_mapped_file file(open_only, MappedFile);  
  76.    
  77.       shared_ptr_owner *owner1 = file.find<shared_ptr_owner>("owner1").first;  
  78.       shared_ptr_owner *owner2 = file.find<shared_ptr_owner>("owner2").first;  
  79.       assert(owner1 && owner2);  
  80.    
  81.       //Check everything is as expected  
  82.       assert(file.find<type_to_share>("object to share").first != 0);  
  83.       assert(owner1->shared_ptr_.use_count() == 2);  
  84.       assert(owner2->shared_ptr_.use_count() == 2);  
  85.       assert(owner1->shared_ptr_.get() == owner2->shared_ptr_.get());  
  86.    
  87.       //Now destroy one of the owners, the reference count drops.  
  88.       file.destroy_ptr(owner1);  
  89.       assert(owner2->shared_ptr_.use_count() == 1);  
  90.    
  91.       //Create a weak pointer  
  92.       weak_ptr_type local_observer1(owner2->shared_ptr_);  
  93.       assert(local_observer1.use_count() == owner2->shared_ptr_.use_count());  
  94.    
  95.       {  //Create a local shared pointer from the weak pointer  
  96.       shared_ptr_type local_shared_ptr = local_observer1.lock();  
  97.       assert(local_observer1.use_count() == owner2->shared_ptr_.use_count());  
  98.       assert(local_observer1.use_count() == 2);  
  99.       }  
  100.    
  101.       //Now destroy the remaining owner. "object to share" will be destroyed  
  102.       file.destroy_ptr(owner2);  
  103.       assert(file.find<type_to_share>("object to share").first == 0);  
  104.    
  105.       //Test observer  
  106.       assert(local_observer1.expired());  
  107.       assert(local_observer1.use_count() == 0);  
  108.    
  109.       //The reference count will be deallocated when all weak pointers  
  110.       //disappear. After that, the file is unmapped.  
  111.    }  
  112.    return 0;  
  113. }  

一般来说,Boost.Interprocess的shared_ptr和weak_ptr使用和它们对应的boost::shared_ptr和boost::weak_ptr是非常类似的,但它们需要更多的模板参数和更多的运行时参数在其构造函数中。

就好像boost::shared_ptr能被存储在STL容器中一样,shared_ptr也能被存储在Boost.Interprocess容器中。

如果一个程序员仅使用shared_ptr来插入动态构建于托管内存片段上的对象至容器中,但不需要与其他对象共享此对象的所有权,则unique_ptr是一个更快速和易用的替代品。

唯一指针

唯一所有权智能指针是非常有用的,它将程序员从非共享对象手工资源中解放出来。Boost.Interprocess的unique_ptr与scoped_ptr很类似,但它是活动的并且能够很容易的插入至Boost.Interprocess容器。这是唯一指针类声明:

   
   
  1. template <class T, class D>  
  2. class unique_ptr;  
  • T是unique_ptr指向的对象的类型。
  • D是删除器,当唯一指针被销毁时(并且如果还拥有对象的所有权),它将删除unique_ptr指向的类型对象。如果删除器定义了一个内部指针类型,unique_ptr将使用一个相同类型的内部指针。因此,如果D::pointer是offset_ptr<T>,则唯一指针将存储一个相对指针而不是原始指针。这允许放置unique_ptr在共享内存和内存映射文件中。

unique_ptr能释放存储的指针的所有权,因此它也能被用做一个回滚函数。此类的一个主要特性是不可拷贝性,仅能移动。当一个唯一指针被移动至另一个,则指针的所有权从源唯一指针转移至目标唯一指针。如果目标唯一指针拥有一个对象,则在拥有新对象之前,原对象先被删除。

unique_ptr也提供了辅助类型用于简化定义和构建唯一指针,它能被放置在托管内存片段中,并且能从片段中正确删除拥有的对象:managed_unique_ptr和make_managed_unique_ptr工具。

下面我们看一个使用unique_ptr的例子,包括创建这些对象的容器:

   
   
  1. #include <boost/interprocess/managed_mapped_file.hpp>  
  2. #include <boost/interprocess/smart_ptr/unique_ptr.hpp>  
  3. #include <boost/interprocess/containers/vector.hpp>  
  4. #include <boost/interprocess/containers/list.hpp>  
  5. #include <boost/interprocess/allocators/allocator.hpp>  
  6. #include <cassert>  
  7.    
  8. using namespace boost::interprocess;  
  9.    
  10. //This is type of the object we'll allocate dynamically  
  11. struct MyType  
  12. {  
  13.    MyType(int number = 0)  
  14.       :  number_(number)  
  15.    {}  
  16.    int number_;  
  17. };  
  18.    
  19. //This is the type of a unique pointer to the previous type  
  20. //that will be built in the mapped file  
  21. typedef managed_unique_ptr<MyType, managed_mapped_file>::type unique_ptr_type;  
  22.    
  23. //Define containers of unique pointer. Unique pointer simplifies object management  
  24. typedef vector  
  25.    < unique_ptr_type  
  26.    , allocator<unique_ptr_type, managed_mapped_file::segment_manager>  
  27.    > unique_ptr_vector_t;  
  28.    
  29. typedef list  
  30.    < unique_ptr_type  
  31.    , allocator<unique_ptr_type, managed_mapped_file::segment_manager>  
  32.    > unique_ptr_list_t;  
  33.    
  34. int main ()  
  35. {  
  36.    //Define file names  
  37.    const char *MappedFile  = "MyMappedFile";  
  38.    
  39.    //Destroy any previous file with the name to be used.  
  40.    struct file_remove  
  41.    {  
  42.       file_remove(const char *MappedFile)  
  43.          : MappedFile_(MappedFile) { file_mapping::remove(MappedFile_); }  
  44.       ~file_remove(){ file_mapping::remove(MappedFile_); }  
  45.       const char *MappedFile_;  
  46.    } remover(MappedFile);  
  47.    {  
  48.       managed_mapped_file file(create_only, MappedFile, 65536);  
  49.    
  50.       //Construct an object in the file and  
  51.       //pass ownership to this local unique pointer  
  52.       unique_ptr_type local_unique_ptr (make_managed_unique_ptr  
  53.          (file.construct<MyType>("unique object")(), file));  
  54.       assert(local_unique_ptr.get() != 0);  
  55.    
  56.       //Reset the unique pointer. The object is automatically destroyed  
  57.       local_unique_ptr.reset();  
  58.       assert(file.find<MyType>("unique object").first == 0);  
  59.    
  60.       //Now create a vector of unique pointers  
  61.       unique_ptr_vector_t *unique_vector =  
  62.          file.construct<unique_ptr_vector_t>("unique vector")(file.get_segment_manager());  
  63.    
  64.       //Speed optimization  
  65.       unique_vector->reserve(100);  
  66.    
  67.       //Now insert all values  
  68.       for(int i = 0; i < 100; ++i){  
  69.          unique_ptr_type p(make_managed_unique_ptr(file.construct<MyType>(anonymous_instance)(i), file));  
  70.          unique_vector->push_back(boost::move(p));  
  71.          assert(unique_vector->back()->number_ == i);  
  72.       }  
  73.    
  74.       //Now create a list of unique pointers  
  75.       unique_ptr_list_t *unique_list =  
  76.          file.construct<unique_ptr_list_t>("unique list")(file.get_segment_manager());  
  77.    
  78.       //Pass ownership of all values to the list  
  79.       for(int i = 99; !unique_vector->empty(); --i){  
  80.          unique_list->push_front(boost::move(unique_vector->back()));  
  81.          //The unique ptr of the vector is now empty...  
  82.          assert(unique_vector->back() == 0);  
  83.          unique_vector->pop_back();  
  84.          //...and the list has taken ownership of the value  
  85.          assert(unique_list->front() != 0);  
  86.          assert(unique_list->front()->number_ == i);  
  87.       }  
  88.       assert(unique_list->size() == 100);  
  89.    
  90.       //Now destroy the empty vector.  
  91.       file.destroy_ptr(unique_vector);  
  92.       //The mapped file is unmapped here. Objects have been flushed to disk  
  93.    }  
  94.    {  
  95.       //Reopen the mapped file and find again the list  
  96.       managed_mapped_file file(open_only, MappedFile);  
  97.    
  98.       unique_ptr_list_t   *unique_list =  
  99.          file.find<unique_ptr_list_t>("unique list").first;  
  100.       assert(unique_list);  
  101.       assert(unique_list->size() == 100);  
  102.    
  103.       unique_ptr_list_t::const_iterator list_it = unique_list->begin();  
  104.       for(int i = 0; i < 100; ++i, ++list_it){  
  105.          assert((*list_it)->number_ == i);  
  106.       }  
  107.    
  108.       //Now destroy the list. All elements will be automatically deallocated.  
  109.       file.destroy_ptr(unique_list);  
  110.    }  
  111.    return 0;  
  112. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习是一种人工智能(AI)的子领域,致力于研究如何利用数据和算法让计算机系统具备学习能力,从而能够自动地完成特定任务或者改进自身性能。机器学习的核心思想是让计算机系统通过学习数据中的模式和规律来实现目标,而不需要显式地编程。 机器学习应用非常广泛,包括但不限于以下领域: 图像识别和计算机视觉: 机器学习在图像识别、目标检测、人脸识别、图像分割等方面有着广泛的应用。例如,通过深度学习技术,可以训练神经网络来识别图像中的对象、人脸或者场景,用于智能监控、自动驾驶、医学影像分析等领域。 自然语言处理: 机器学习在自然语言处理领域有着重要的应用,包括文本分类、情感分析、机器翻译、语音识别等。例如,通过深度学习模型,可以训练神经网络来理解和生成自然语言,用于智能客服、智能助手、机器翻译等场景。 推荐系统: 推荐系统利用机器学习算法分析用户的行为和偏好,为用户推荐个性化的产品或服务。例如,电商网站可以利用机器学习算法分析用户的购买历史和浏览行为,向用户推荐感兴趣的商品。 预测和预测分析: 机器学习可以用于预测未来事件的发生概率或者趋势。例如,金融领域可以利用机器学习算法进行股票价格预测、信用评分、欺诈检测等。 医疗诊断和生物信息学: 机器学习在医疗诊断、药物研发、基因组学等领域有着重要的应用。例如,可以利用机器学习算法分析医学影像数据进行疾病诊断,或者利用机器学习算法分析基因数据进行疾病风险预测。 智能交通和物联网: 机器学习可以应用于智能交通系统、智能城市管理和物联网等领域。例如,可以利用机器学习算法分析交通数据优化交通流量,或者利用机器学习算法分析传感器数据监测设备状态。 以上仅是机器学习应用的一部分,随着机器学习技术的不断发展和应用场景的不断拓展,机器学习在各个领域都有着重要的应用价值,并且正在改变我们的生活和工作方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值