调用类型不明的类的方法

问题描述 投票:0回答:3

我有一个名为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);

现在,我明白了为什么会出错,但问题是我不知道如何修改代码或更改设计。请让我知道我的缺失和误解。提前致谢。

c++ pointers templates void
3个回答
0
投票

您需要为所有订户定义一个通用接口,然后将该接口用作m_subscriber的类型。粗暴地将您收到的任何参数强制转换为已定义的类型只会导致未定义的行为。


0
投票

您无需为此使用模板。只需为您的订阅者使用基类。 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
投票

使用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); }
© www.soinside.com 2019 - 2024. All rights reserved.