i found code using std::shared_ptr perform arbitrary cleanup @ shutdown. @ first thought code not possibly work, tried following:
#include <memory> #include <iostream> #include <vector> class test { public: test() { std::cout << "test created" << std::endl; } ~test() { std::cout << "test destroyed" << std::endl; } }; int main() { std::cout << "at begin of main.\ncreating std::vector<std::shared_ptr<void>>" << std::endl; std::vector<std::shared_ptr<void>> v; { std::cout << "creating test" << std::endl; v.push_back( std::shared_ptr<test>( new test() ) ); std::cout << "leaving scope" << std::endl; } std::cout << "leaving main" << std::endl; return 0; } this program gives output:
at begin of main. creating std::vector<std::shared_ptr<void>> creating test test created leaving scope leaving main test destroyed i have ideas on why might work, have internals of std::shared_ptrs implemented g++. since these objects wrap internal pointer counter cast std::shared_ptr<test> std::shared_ptr<void> not hindering call of destructor. assumption correct?
and of course more important question: guaranteed work standard, or might further changes internals of std::shared_ptr, other implementations break code?
the trick std::shared_ptr performs type erasure. basically, when new shared_ptr created store internally deleter function (which can given argument constructor if not present defaults calling delete). when shared_ptr destroyed, calls stored function , call deleter.
a simple sketch of type erasure going on simplified std::function, , avoiding reference counting , other issues can seen here:
template <typename t> void delete_deleter( void * p ) { delete static_cast<t*>(p); } template <typename t> class my_unique_ptr { std::function< void (void*) > deleter; t * p; template <typename u> my_unique_ptr( u * p, std::function< void(void*) > deleter = &delete_deleter<u> ) : p(p), deleter(deleter) {} ~my_unique_ptr() { deleter( p ); } }; int main() { my_unique_ptr<void> p( new double ); // deleter == &delete_deleter<double> } // ~my_unique_ptr calls delete_deleter<double>(p) when shared_ptr copied (or default constructed) deleter passed around, when construct shared_ptr<t> shared_ptr<u> information on destructor call passed around in deleter.
Comments
Post a Comment