As others have pointed out, you cannot guard against malicious users of Graph. I'll assume that you don't want to, either, and that you're in the position of the Graph author trying to prevent users of the class from misunderstanding the ownership semantics of Graph while implementing Algorithm(s).
You could hand out only shared_ptr<Guard> by using the Named Constructor Idiom, which should prevent all but the most clueless of coders from attempting to delete Graph, however, Algorithm writers could still use Graph * mGraph as a member variable and pass shared_ptr<>::get() when constructing it...
To make this watertight for all but the most determined of malicious coders, you need to use the Counted Body Idiom. In short: wrap Graph*s with a GraphHandle class that is passed by-value and proxies Graph's API. It's a bit like only ever creating shared_ptr<Graph>s, but it prevents access to the 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 );
}
// do NOT provide an accessor for this->graph!
// proxied API:
void doSomething() {
graph->doSomething();
}
// ...
};
class Algorithm {
// ...
GraphHandle graph;
};
This way, Algorithm can no longer delete the Graph.
Algorithm authors can of course still use Graph directly. To prevent this, make Graph private API and hide it completely behind GraphHandle. You can see this in production in the DOM implementation of Qt.
As an aside:
Using shared_ptr in the implementation of GraphHandle doesn't mean GraphHandle necessarily owns the Graph. You can hold a shared_ptr<Graph> outside of the GraphHandle, or, if the rest of the code uses naked pointers, you can just pass nodelete as the shared_ptrs deleter:
struct nodelete {
template <typename T>
void operator()( T* ) {}
};
// ...
Graph * nakedGraph = ...;
const shared_ptr<Graph> sharedGraph( nakedGraph, nodelete() );
GraphHandle handledGraph( sharedGraph );