
I have a class diagram with the following base classes: class Object; class Ident { ... private: ... friend class Object; void set_object(Object* obj) { object_ = obj; } private: ... Object* object_; }; class Object { ... public: Ident* ident() { return ident_.get(); } const Ident* ident() const { return ident_.get(); } shared_ptr<Ident> ident_ptr() { return ident_; } protected: Object(shared_ptr<Ident> ident) : ident_(ident) { ident_->set_object(this); } virtual ~Object() { ident_->set_object(0); } private: shared_ptr<Ident> ident_; }; An Object in memory always has an Ident, which it shares with client code, but the Ident of an Object can be loaded before the object itself, and will also remain after the Object is gone, as long as client code references it. Ident has a "back" pointer to its Object, which is maintained by Object directly via friendship. (yes, the design is tightly coupled). In effect Ident is almost like a "weak" proxy to its Object. Then there are derived class pairs from Ident+Object: class VehiculeIdent : public Ident { /* Vehicule-specific ident members */ } class Vehicule : public Object { protected: Vehicule() : Object(shared_ptr<VehiculeIdent>(new VehiculeIdent)) {} public: // covariant return type VehiculeIdent* ident() { return polymorphic_downcast<VehiculeIdent*>(Object::ident()); } const VehiculeIdent* ident() const { /* same as above */ } }; Vehicule is itself the base of a base hierarchy (Car, Bike, etc...), and I have other such "roots" (which all derive from Object). There's a manager class per root which composes a Boost.MultiIndex container specific to each root identity, which a simple interface like so: typedef multi_index_container< shared_ptr<VehiculeIdent>, indexed_by< ... > > > VehiculeIndex; class VehiculeMgr { public: ... bool bind_vehicule(Vehicule* v); void unbind_vehicule(Vehicule* v); private: VehiculeIndex index_; }; The problem I have is that I need a shared_ptr<VehiculeIdent> to insert to the B.MI index which I obtain from the Vehicule*, but given the API above I can only obtain a VehiculeIdent* or a shared_ptr<Ident>, both of which are inadequate to interact with the B.MI. I worked around this issue so far by changing VehiculeIdent like so: class VehiculeIdent : public Ident, public enable_shared_from_this<VehiculeIdent> { ... shared_ptr<VehiculeIdent> as_shared_ptr() { return shared_from_this(); } }; at which point I can now write for example: bool VehiculeMgr::bind_vehicule(Vehicule* v) { return index_.insert(v->ident()->as_shared_ptr()).second; } But this solution seems unsatisfactory to me, because it forces the derivation and additional as_shared_ptr member in the public API of all Ident-deriving "root ident" classes, which I only need it inside VehiculeMgr (whose B.MI index is private). So long story short, is there a clean way to obtain a shared_ptr<VehiculeIdent> from a shared_ptr<Ident> which one "knows" is a VehiculeIdent, to avoid my as_shared_ptr hack above? Thanks for any help, --DD PS: I'm happy to get advice on the design overall as well, separate from this main subject of this post.