After reading the article, are you finding it troublesome to get started and getting rid of your pointers?
A handle is just a unique integral number assigned by some authority, a manager. The outside world must not induce anything from the handle itself.
In order to get the contents behind a handle, you must ask a manager, which will do a lookup (implementation of which is private and hidden!). Every time. You don't store pointers to the returned values. You don't care and mustn't care where they are in memory.
Think about it this way: Instead of pointing your finger towards a troll that attacked you and risking that the troll gets lost behind a wall (and aliens abduct it from there) so you'd be pointing to a void space where you just think a troll should be, just remember the number tattooed on the troll's forearm. Every time, every frame, when you want something with it, ask the Troll Registration Bureau: "Hey, is troll XY still alive? And if yes, where is it?"
The nuts and bolts would be how to assign unique handles, how to organise the contents in memory, how to to optimise the cache access... however first you need to set up the interface and throw in any basic implementation, and only optimise in case it is a bottleneck.
The troll manager might have a hash-map<Handle,Troll> style dictionary, in a naive implementation. Every time it's asked, it'll look into the hash-map and return nullptr if it doesn't find anything (or anything alive). And if it does find it, it can actually return a POINTER (!) but you must not store it for later use. Just use it and forget it. Next time, it might return a different pointer for the same handle, for example if it did some kind of defragmentation.