The “notify” behavior of shared_ptr
requires reference counting the reference count control block. shared_ptr
‘s reference count control block(s) use separate reference counts for this. weak_ptr
instances maintain references to this block, and weak_ptr
s themselves prevent the reference count control block from being delete
ed. The pointed-to object has its destructor called when the strong count goes to zero (which may or may not result in delete
ion of the memory where that object was stored), and the control block is delete
ed only when the weak reference count goes to zero.
unique_ptr
‘s tenet is that it has zero overhead over a plain pointer. Allocating and maintaining reference count control blocks (to support weak_ptr
-ish semantics) breaks that tenet. If you need behavior of that description, then you really want shared semantics, even if other references to the object are non-owning. There’s still sharing going on in that case — the sharing of the state of whether or not the object has been destroyed.
If you need a generic nonowning reference and don’t need notification, use plain pointers or plain references to the item in the unique_ptr
.
EDIT:
In the case of your example, it looks like Victim
should ask for a Trebuchet&
rather than a Trebuchet*
. Then it’s clear who owns the object in question.
class World
{
public:
Trebuchet& trebuchet() const { return *m_trebuchet.get(); }
private:
std::unique_ptr< Trebuchet > m_trebuchet;
};
class Victim
{
public:
Victim( Trebuchet& theTrebuchet ) : m_trebuchet( theTrebuchet ) {}
~Victim()
{
delete m_trebuchet; // Compiler error. :)
}
private:
Trebuchet& m_trebuchet; // Non-owning.
};
shared_ptr< Victim > createVictim( World& world )
{
return make_shared< Victim >( world.trebuchet() );
}