I have been reading "Game Engine Architecture - Jason Gregory" and he makes the statement:
A handle acts like a smart pointer in many ways, but it is simpler to implement and tends to be less prone to problems. A handle is basically an integer index into a global handle table. The handle table, in turn, contains pointers to the objects to which the handles refer. To create a handle, we simply search the handle table for the address of the object in question and store its index in the handle.
Gregory, Jason; Jeff Lander; Matt Whiting; Lander, Jeff; Whiting, Matt (2011-12-13). Game Engine Architecture (Page D). A. K. Peters. Kindle Edition.
He then gives a skeletal implementation of a handle table (where handles simply are integer indexes into an array of pointers). What I am not really convinced of is why you would use a handle table vs raw pointers unless you are planning to relocate what is being pointed to?
He does say that it allows you to null out an entry in the table and all handles automatically reflect that. However It would seem that you still need to have a predetermined lifetime and ownership of all objects, and if that is the case it should be possible to simply make sure at the point that you delete the object that noone points to it (best case through some design, worst case through callbacks perhaps).
Smart pointers would allow you to have shared ownership, and certainly you might store a reference count in the handle table , but I am not convinced (and the book gives no evidence to suggest ) that doing so would be more run-time efficient than using say boost::intrusive_ptr.
Maybe I am missing something , but to me it seems more like a choice between raw pointers vs smart pointers (depending on the particular case) whether the lifetime is very well defined (by single ownership), or not.