"Handle" doesn't have a widely agreed upon meaning with respect to C++. Different people use it to mean entirely different things (e.g., on Windows, "handle" does have a fairly well-defined meaning, so people programming Windows in C++ tend to use it the way Windows does).
As far as implementation in another class, that sounds more like a pimpl than what most people would usually call a handle. If that's the sort of thing you're talking about, it's quite a bit different from inheritance in both implementation and use. In fact, in many ways it's kind of the opposite: inheritance allows classes that are different from each other to be treated as if they were the same. With a pimpl, you have two classes that are identical (in some ways) but you still keep them entirely separate.
As to where/why you use them: with an interface (usually an ABC, in C++) you allow new derived classes to be manipulated via an existing interface, so existing code can use your new code without that existing code needing modification to do so.
pimpl is typically used primarily as a compiler firewall -- if you have some code that's changing frequently, but you don't want to re-compile everything that depends on it every time you change it, a pimpl can be helpful (though definitely not a panacea).
A handle is typically used to mean an opaque data type -- a "magic cookie" that gives you access to some capabilities, but which you can't/don't look at or manipulate directly at all. To some extent, you could consider any reference/pointer to almost any class as a handle (of sorts), but it's pretty unusual to hear/see the term used that way. More often it's something like a FILE *
in C -- when you call fopen
, it gives you the FILE *
. Anytime you want to operate on the handle you opened, you pass that same FILE *
back to the function you're going to use. You, however, aren't ever supposed to look "inside" to see what it points at, how that's used, or much of anything else (and at the Unix level using open/lseek/lread, etc., a file descriptor is pretty much the same way).
Perhaps you're thinking of something close to the handle/body idiom that was popular in relatively early C++. In this idiom, you did have implementation in another class. Specifically, the "handle" typically provided reference counting, and the body the implementation of whatever actions were needed on the single item to which you had those multiple (counted) references. The handle "handled" the reference count, and passed almost everything else through to the implementation class. This usage is no longer common for the simple reason that reference counting has largely fallen out of favor. Especially in a multi-threaded environment, reference counting can (and frequently does) have fairly substantial speed penalties, so its use is now relatively unusual (where at one time it was nearly expected of most classes that might manage substantial amounts of data).