jwsc
jwsc

Reputation: 945

static_cast with unrelated classes

I have following class structure:

enter image description here

Now I have a Device pointer, where I know that it is of type WiredHeadphone or RadioHeadphone. I need to cast this pointer to HeadphoneInterface.

In a perfect world I would just use a dynamic_cast. Unfortunately I am on an embedded platform which does not support dynamic_cast at all. Currently I do this:

HeadphoneInterface *GetDeviceAsHeadphone(Device* dev) {
    // use my own type system to identify the actual type and cast accordingly:
    if(dev->GetType() == Type_WiredHeadphone) {
        return static_cast<HeadphoneInterface*>((WiredHeadphone *)dev);
    } else if(dev->GetType() == Type_RadioHeadphone) {
        return static_cast<HeadphoneInterface*>((RadioHeadphone *)dev);
    } else {
        return NULL;
    }
}

This is ugly as hell and not maintainable. There will be more Headphone devices in the future, and I don't want to update this function every time. Is there a better way to solve this?

Upvotes: 1

Views: 265

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136256

You can add a virtual function to Device interface that does the (cross) cast to HeadphoneInterface for you:

struct HeadphoneInterface;

struct Device {
// ...
    virtual HeadphoneInterface* getHeadphoneInterface() noexcept { return 0; }
// ...
};

And override the function in WiredHeadphone and RadioHeadphone to return a non-null pointer to HeadphoneInterface:

struct WiredHeadphone : WiredDevice, HeadphoneInterface {
    HeadphoneInterface* getHeadphoneInterface() noexcept override { return this; }
};

Then GetDeviceAsHeadphone becomes:

inline HeadphoneInterface* GetDeviceAsHeadphone(Device* dev) noexcept {
    return dev->getHeadphoneInterface();
}

Notice that no explicit cast is required here.

Upvotes: 3

Related Questions