[C++] What exactly are handles?

Started by
4 comments, last by zyrolasting 14 years, 1 month ago
Are handles like HWND and FMUSIC_HANDLE just pointers to the beginning of structures, and everything else must know the offsets to members?
Advertisement
It doesn't matter. The point behind handles is that you neither know nor care what they actually are. Some of them might be pointers; others might be indices into OS tables. This can change from OS version to OS version so that what was once an index is now a pointer or vice versa.
A handle is a handle is a handle. Individual implementations may have specific characteristics which have been known to have been abused, but a handle is opaque identifier, a token.

Quote:Are handles like HWND and FMUSIC_HANDLE just pointers to the beginning of structures, and everything else must know the offsets to members?

They might be, or they might not be. HWND and FMUSIC_HANDLE are handles, opaque types identifying individual resources. They are not pointers, ints, offsets or anything similar, even though particular implementation might treat them as such.

Handles in APIs have fallen out of favor since users treated them as concrete types and made unwarranted assumptions about their meaning.
Quote:Handles in APIs have fallen out of favor since users treated them as concrete types and made unwarranted assumptions about their meaning.


What did handles give way for? APIs don't exactly have a goal of keeping things visible, and handles certainly did a good job of hiding things from me.
Quote:Original post by zyrolasting

What did handles give way for?


Pointers and instances.

Factory pattern, interfaces and similar.

Quote:APIs don't exactly have a goal of keeping things visible, and handles certainly did a good job of hiding things from me.


Unfortunately, handles were almost always implemented as integers, so they didn't really hide anything, and due to value semantics, often caused whole set of problems (socket and file descriptors come to mind). In addition, safe handles require extra check on each use. This is especially true when working across two authorities, such as application vs. file system, where file system is modified independently of application, and handle might become invalid with no way to signal that to application.

Using type-safe and strongly typed interfaces, usually on per-process scope is better in practice.

Technically, in managed languages, all "pointers" or instances are represented with handles, but enforced at language or VM level, meaning they are safe without incurring conventional performance penalty. Applications deal only with interfaces or instances, all of which are guaranteed to be valid.
If I may, let me ask one more thing about a design pattern. FMOD::System uses a factory method, but it's methods are not virtual.

FMOD_RESULT F_API setOutput(FMOD_OUTPUTTYPE output);FMOD_RESULT F_API getOutput(FMOD_OUTPUTTYPE *output);...


To be fair, the factory routine casts to what I assume is a base class, but FMOD::System does not derive from it. How can you add members to an object like this?

This topic is closed to new replies.

Advertisement