Вызов метода класса с неопознанным типом - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть класс с именем MyClass, на который подписан другой класс. Когда происходят какие-то события, MyClass должен уведомить подписчиков. Я пытаюсь использовать шаблон для типа подписчика. Потому что я не хочу позволять другим (отвечающим за класс абонента) заботиться об изменении MyClass для подписки. Итак, я написал следующие коды:

class MyClass {

public:

    template<typename T>
    void subscribeEvents(const T &controller)
    {
        m_subscriber = static_cast<T*>(m_subscriber);
        m_subscriber = &controller;
    }

    void notifyPositionChanged(const long &position) const {

          (m_subscriber)->onPositionChanged(position);
    }

private:

    void m_subscriber;  // will be changed to array or something else

}

На самом деле у объекта controller есть метод с именем onPositionChanged.

Но, как вы знаете, он не скомпилирован для этой строки.

(m_subscriber)->onPositionChanged(position);

Теперь я понимаю, почему это ошибка, но проблема в том, что я не знаю, как изменить коды или изменить свой дизайн. Пожалуйста, дайте мне знать, что мне не хватает и недоразумение. Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 11 февраля 2020

Вам не нужно использовать шаблон для этого. Просто используйте базовый класс для своих подписчиков. И MyClass работает на вашем базовом классе

class ISubscribe {
public:
    virtual void onPositionChanged(const long &position) = 0;
};

class MyClass {
public:

    void subscribeEvents(ISubscribe *controller)
    {
        m_subscriber = controller;
    }

    void notifyPositionChanged(const long &position) const {

      (m_subscriber)->onPositionChanged(position);
    }
private:

    ISubscribe *m_subscriber;  // will be changed to array or something else
};

class SampleSubscriber : public ISubscribe {
public :
    void onPositionChanged(const long &position) override{
              ...
    }
};

void main() {
    SampleSubscriber s;
    MyClass m;

    m.subscribeEvents(&s);
 ....
}
0 голосов
/ 11 февраля 2020

Использование std::function:

class MyClass {
public:

    template<typename CALLBACK>
    void subscribeEvents(CALLBACK &&controller)
    {
        m_subscriber = std::forward<CALLBACK>(controller);
    }

    void notifyPositionChanged(const long &position) const
    {
        if (m_subscriber)
            m_subscriber(position);
    }

private:
    std::function<void(const long&)> m_subscriber;
}

Это дает абоненту полную свободу того, что он хочет подписаться. Например:

there.subscribeEvents([this](const long &pos) { handlePosChange(pos); }
0 голосов
/ 11 февраля 2020

Вам необходимо определить общий интерфейс для всех ваших подписчиков, а затем использовать этот интерфейс в качестве типа m_subscriber. Своевременное приведение любого параметра к определенному типу приведет только к неопределенному поведению.

...