c++ - How to prevent an object from being deleted in places where it shouldn't, at compile-time? -


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 graphs 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_ptrs deleter:

struct nodelete {     template <typename t>     void operator()( t* ) {} };  // ... graph * nakedgraph = ...; const shared_ptr<graph> sharedgraph( nakedgraph, nodelete() ); graphhandle handledgraph( sharedgraph ); 

Comments