c++ - How should I store a list of weak pointers in the factory class? -
there factory class in project, returns std::shared_ptr<myclass>
, if create
method called. factory not owner, maintains list of created objects. factory needs iterate on created objects still used, or count them.
i implemented using std::vector<std::weak_ptr<myclass>>
. iteration looks this:
for (std::weak_ptr<myclass> wp : weak_list) { if (auto sp = wp.lock()) { //.. } }
the create
function:
std::shared_ptr<myclass> create(/* ... */) { std::shared_ptr<myclass> obj = std::make_shared<myclass>(); //... weak_list.push_back(obj); return obj; }
is vector best container list this? maybe std::set
better.
if implement using vector, have check regularly expired pointers in list , remove them
what preferred way store list of weak pointers in factory class?
by default use vector.
sets not self clean expired pointers, , manual cleaning process same.
consider cleaning dead elements before iterating, , iterating on copy of weak list (in case iteration mutates weak list).
if need immediate cleaning of dangling weak ptrs, modify shared ptr unregister weak list when last strong reference goes away. requires work make shared involving aligned storage, manual construction , destruction, helper struct , aliasing contructor shared ptr.
template<class t> struct shared_helper { typename std::aligned_storage<sizeof(t),alignof(t)::type data; t* get(){ return reinterpret_cast<t*>(&data); } bool constructed = false; weak_list<t>* list=0; std::weak_ptr<t> self; ~shared_helper(){ if (constructed){ get()->~t(); constructed=false; } if (list) list->erase(self); } template<class...ts> t* emplace(ts&&...ts){ t* r = ::new( (void*)&data ) t(std::forward<ts>(ts)...); constructed = true; return r; } }; template<class t, class...args> std::shared_ptr<t> make_and_register( weak_list<t>& list, args&&...args ){ auto r = std::make_shared<shared_helper<t>>(); if(!r) return {}; r->emplace( std::forward<args>(args)... ); std::shared_ptr<t> ptr( r, r->get() ); r->self = ptr; list.insert(ptr); r->list = &list return ptr; }
which bit obtuse, untested , uncompiled. in case, set or unordered set weak list makes sense, use fast lookup instantly clean weak list when last strong reference expires.
Comments
Post a Comment