static_cast с несвязанными классами - PullRequest
0 голосов
/ 22 ноября 2018

У меня следующая структура класса:

enter image description here

Теперь у меня есть указатель Device, где я знаю, что он имеет тип WiredHeadphoneили RadioHeadphone.Мне нужно привести этот указатель к HeadphoneInterface.

В идеальном мире я бы просто использовал dynamic_cast.К сожалению, я на встроенной платформе, которая вообще не поддерживает dynamic_cast.В настоящее время я делаю это:

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;
    }
}

Это ужасно ужасно и не подлежит ремонту.В будущем будет больше устройств для наушников, и я не хочу обновлять эту функцию каждый раз.Есть ли лучший способ решить эту проблему?

1 Ответ

0 голосов
/ 22 ноября 2018

Вы можете добавить виртуальную функцию к интерфейсу Device, который выполняет (перекрестное) приведение к HeadphoneInterface для вас:

struct HeadphoneInterface;

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

И переопределить функцию в WiredHeadphone и RadioHeadphone длявернуть ненулевой указатель на HeadphoneInterface:

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

Тогда GetDeviceAsHeadphone становится:

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

Обратите внимание, что здесь не требуется явное приведение.

...