ar.load_pointer函数的简要说明,这个函数是动态生成类实例的功能函数,前面没有什么要跟的都是处理版本对象id什么的代码,值得记录的就是bpis_ptr->load_object_ptr( ar , object_id_vector[ui].address , co.file_version )这个函数是比较关键的函数,具体的代码实现如下
template<class T, class Archive> BOOST_DLLEXPORT void pointer_iserializer<T, Archive>::load_object_ptr( basic_iarchive & ar, void * & x, const unsigned int file_version ) const { auto_ptr_with_deleter<T> ap(heap_allocator<T>::invoke()); if(NULL == ap.get()) boost::throw_exception(std::bad_alloc()) ; T * t = ap.get(); x = t;
// this addresses an obscure situtation that occurs when load_constructor // de-serializes something through and a pointer. ar.next_object_pointer(t);
Archive & ar_impl = boost::smart_cast_reference<Archive &>(ar); boost::serialization::load_construct_data_adl<Archive, T>( ar_impl, t, file_version ); ar_impl >> boost::serialization::make_nvp(NULL, * t); ap.release(); }
红色部份的代码为对象分配内存的代码,其中用到了auto_ptr_with_deleter这个智能指针,和一个heap_allocator<T>堆的分配器,这两个工具类的实现代码很简单,看看他们的代码就清楚,调用完这一句之会就会为test对象分配一块儿堆的内存做为a指针指向的内容,注意这个时候还没有调用到test的构造函数,只是为这个对象分配了一个空间因为在heap_allocator<T>中分配内存使用内存用的是operator new (sizeof(T)),这个操作只是分配了空间并没有调用test的构造函数。
紫色部份的代码是真正的调用构造函数的部份,调试跟踪后就会发现最后通过调用
template<class Archive, class T> static void construct(Archive & /* ar */, T * t){ // default is inplace invocation of default constructor // Note the :: before the placement new. Required if the // class doesn't have a class-specific placement new defined. ::new(t)T; } 这个函数来调用test对象的构造函数的,到了这儿test* a这个对象才算真正创建完成了。
|