The libuv handles have a void* data
field to carry around any context information (pretty standard pattern for callbacks in C-land). However, since I'm working in C++-land, I would like to use inheritance to directly store context in the handle. The main advantage is in storing multiple context items which IIUC requires heap allocations to "combine" them into a single pointer, say, std::tuple<...>*
or some temporary struct (correct me if I'm wrong here and I can avoid heap allocations even in C-land).
My main apprehensions are:
So, can I inherit from libuv handles safely in C++? Bonus points if you can clarify the above points as well.
If you are the one allocating the handles yourself and then passing them to libuv, there is nothing stopping you from inheriting them. You are allowed to allocate them however you want. You could make them a member of your class, but you could also make them a base of your class.
The compiler isn't allowed to change the libuv handle's memory layout just because it's a base class. It's allowed to decide where the base goes in the overall class structure, but it's not allowed to change the base itself. (Otherwise, pointers to the base class would have to work differently, depending on whether you allocated the an instance of the base class or the derived class!)
Since the compiler can't change the memory layout, whatever libuv does is irrelevant. If it works with normal libuv handle objects, it'll still work when they're used as a base class.
Note: If inheriting from a libuv handle still makes you uncomfortable, you could allocate the handle as a member of your class, and store a pointer to the whole class in libuv's "context" field.