i have classes graph
, algorithm
:
class graph { ... }; class algorithm { ... private: graph * mgraph; ... };
i want algorithm able mgraph
except deleting it. i.e. want detect (at compile time) if somewhere in algorithm i'm deleting graph. there (elegant) way such thing? (the way realized making graph
s destructor private friend classes have permission delete it)
as others have pointed out, cannot guard against malicious users of graph
. i'll assume don't want to, either, , you're in position of graph
author trying prevent users of class misunderstanding ownership semantics of graph
while implementing algorithm
(s).
you hand out shared_ptr<guard>
using named constructor idiom, should prevent clueless of coders attempting delete graph
, however, algorithm
writers still use graph * mgraph
member variable , pass shared_ptr<>::get()
when constructing it...
to make watertight determined of malicious coders, need use counted body idiom. in short: wrap graph*
s graphhandle
class passed by-value , proxies graph
's api. it's bit ever creating shared_ptr<graph>
s, prevents access raw pointer:
class graph { public: // ... void dosomething(); }; class graphhandle { shared_ptr<graph> graph; public: explicit graphhandle( const shared_ptr<graph> & graph ) : graph( graph ) { assert( graph ); } // not provide accessor this->graph! // proxied api: void dosomething() { graph->dosomething(); } // ... }; class algorithm { // ... graphhandle graph; };
this way, algorithm
can no longer delete graph
.
algorithm authors can of course still use graph
directly. prevent this, make graph
private api , hide behind graphhandle
. can see in production in dom implementation of qt.
as aside:
using shared_ptr
in implementation of graphhandle
doesn't mean graphhandle
owns graph
. can hold shared_ptr<graph>
outside of graphhandle
, or, if rest of code uses naked pointers, can pass nodelete
shared_ptr
s deleter:
struct nodelete { template <typename t> void operator()( t* ) {} }; // ... graph * nakedgraph = ...; const shared_ptr<graph> sharedgraph( nakedgraph, nodelete() ); graphhandle handledgraph( sharedgraph );
Comments
Post a Comment