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