// demo_shared_ptr.cpp : demonstrates adding serialization to a template // // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org for updates, documentation, and revision history. #include #include #include #include #include #include #include #include #include // This refers to where the serialization library was built to. You // will need to change it on your system. #pragma comment(lib, "c:\\nbtools\\rel\\lib\\debug\\boost_serialization-vc71-mt-gd-1_31.lib") // This macro is used to export GUIDS for shared pointers to allow // the serialization system to export them properly. #define HACK_SERIALIZATION_EXPORT_SHARED_POINTER(T) \ typedef boost::detail::sp_counted_base_impl< \ T *, \ boost::checked_deleter< T > \ > __shared_ptr_ ## T; \ BOOST_CLASS_EXPORT(__shared_ptr_ ## T) // This is a simple class. It contains a counter of the number // of objects of this class which have been instantiated. class A { private: friend class boost::serialization::access; int x; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & x; } public: static int count; A::A(){++count;} // default constructor virtual A::~A(){--count;} // default destructor }; // B is a subclass of A class B : public A { private: friend class boost::serialization::access; int y; template void serialize(Archive & ar, const unsigned int /* file_version */){ ar & boost::serialization::base_object(*this); } public: static int count; B::B() : A() {}; virtual B::~B() {}; }; // Tell the serialization system about these classes. BOOST_CLASS_EXPORT(A) BOOST_CLASS_EXPORT(B) // Tell the serialization system about shared_ptrs to these classes. HACK_SERIALIZATION_EXPORT_SHARED_POINTER(A) HACK_SERIALIZATION_EXPORT_SHARED_POINTER(B) int A::count = 0; // Display information about the objects contained in two shared_pointers. void display(boost::shared_ptr &spa, boost::shared_ptr &spa1) { std::cout << "a = 0x" << std::hex << spa.get() << " "; if (spa.get()) std::cout << "is a " << typeid(*(spa.get())).name() << "* "; std::cout << "use count = " << std::dec << spa.use_count() << std::endl; std::cout << "a1 = 0x" << std::hex << spa1.get() << " "; if (spa1.get()) std::cout << "is a " << typeid(*(spa1.get())).name() << "* "; std::cout << "use count = " << std::dec << spa1.use_count() << std::endl; std::cout << "unique element count = " << A::count << std::endl; } // Run tests by serializing two shared_ptrs into an archive of type // OARCH, clearing them (deleting the objects) and then reloading the // objects back from an archive of type OARCH. template void test_save_and_load(boost::shared_ptr& first, boost::shared_ptr& second) { // Display display(first, second); // Save { std::cout << std::endl << "Saving..." << std::endl; std::ofstream ofs("testfile"); OARCH oa(ofs); oa << first; oa << second; } // Clear the pointers, thereby destroying the objects they contain first.reset(); second.reset(); display(first, second); // Load { std::cout << std::endl << "Loading..." << std::endl; std::ifstream ifs("testfile"); IARCH ia(ifs); ia >> first; ia >> second; } display(first, second); // Clear the pointers, thereby destroying the objects they contain first.reset(); second.reset(); } // This does the tests int main(int argc, char *argv[]) { // These are our shared_ptrs boost::shared_ptr spa; boost::shared_ptr spa1; // Try to save and load pointers to As, to a text archive spa = boost::shared_ptr(new A); spa1 = spa; std::cout << std::endl << "--------------"; std::cout << std::endl << "Testing with pointers to As on a text archive." << std::endl; test_save_and_load(spa, spa1); // Try to save and load pointers to Bs, to a text archive spa = boost::shared_ptr(new B); spa1 = spa; std::cout << std::endl << "--------------"; std::cout << std::endl << "Testing with pointers to Bs on a text archive." << std::endl; test_save_and_load(spa, spa1); // Try to save and load pointers to As, to a binary archive spa = boost::shared_ptr(new A); spa1 = spa; std::cout << std::endl << "--------------"; std::cout << std::endl << "Testing with pointers to As on a binary archive." << std::endl; test_save_and_load(spa, spa1); // Try to save and load pointers to Bs, to a binary archive spa = boost::shared_ptr(new B); spa1 = spa; std::cout << std::endl << "--------------"; std::cout << std::endl << "Testing with pointers to Bs on a binary archive." << std::endl; test_save_and_load(spa, spa1); // obj of type A gets destroyed // as smart_ptr goes out of scope return 0; }