C++ 继承类中的回调参数类型不匹配

C++ 继承类中的回调参数类型不匹配,c++,callback,arguments,inherited,C++,Callback,Arguments,Inherited,我正试图根据顶部答案中的链接代码实现一个事件管理器: 然而,当我尝试注册回调时,我得到了一个错误。 我肯定它与typedef有关,我承认我不确定它到底是如何工作的,但它在链接代码中的形式是完全相同的。 B类应该是从接口继承的,那么为什么类型不同呢? 我已将代码压缩为下面的最小示例 #include <iostream> class Interface; typedef void (Interface::*Callback)(void *data); class Interfac

我正试图根据顶部答案中的链接代码实现一个事件管理器:

然而,当我尝试注册回调时,我得到了一个错误。 我肯定它与typedef有关,我承认我不确定它到底是如何工作的,但它在链接代码中的形式是完全相同的。 B类应该是从接口继承的,那么为什么类型不同呢? 我已将代码压缩为下面的最小示例

#include <iostream>

class Interface;
typedef void (Interface::*Callback)(void *data);

class Interface
{
    public:
        void Register    (Callback func);

};

void Interface::Register(Callback func)
{
    std::cout << "Register" << std::endl;
}


class B : public Interface
{
    public:
        B();
        void Echo(void *data);
};

B::B()
{
    Register( (Callback)Echo );
}

void B::Echo(void *data)
{
    std::cout << "Echo" << std::endl;
}


int main()
{
    B b;
    return 0;
}
谁能解释一下我做错了什么?
谢谢

我认为您最好使用std::function(c++11)或boost::function(c++03+boost)

这不是Java,接口不是语言定义的东西。这样,您就可以拥有一个接口,您可以选择实现哪个部分,如果回调与您的类无关,那么就不要实现它

void*不好的原因有很多。从C++ FAQ

避免void*(将它们放在低级函数和数据结构中 如果您真的需要它们并提供类型安全接口,通常 模板(适用于您的用户)

搜索“void*”

<>但基本上空隙*绕过了C++加入的所有类型安全性。这是对C语言的一种攻击,以弥补它没有任何多态性或泛型代码的事实。

正如正确指出的那样,
Echo
不是
接口的成员,因此
B::Echo
不符合
接口::*回调
。但您可以使用模板来实现这一点,例如:

template <class T> class Interface {
public:
    typedef void (T::*Callback)(void *data);
    void Register(Callback func) {
        std::cout << "Register" << std::endl;
    }
    // ...
};

class B : public Interface<B> {
public:
    B() {
        Register(&B::Echo);
    }
    void Echo(void *data) {
        // Do something
    }
};
模板类接口{
公众:
typedef void(T::*回调)(void*数据);
无效寄存器(回调函数){

STD::你没有一个函数<代码>接口::回声< /代码>,简单的说……你可能想考虑使用<代码> Boo::函数< /C>或等效工具……我认为使用模板将是最好的解决方案。我不知道我连接的代码是如何工作的,也许它不:PI不能使用虚拟,因为每次回调。对于每个继承的类,都需要在接口类中实现。使用void*有什么危险?请阅读我在答复底部附加的内容。@Shootfast:避免
void*
是一个很好的建议。主要原因是
void*
可以隐式转换为任何不安全的指针类型,并且我不能给你一些调试时间。
#include <iostream>

class Interface;
typedef void (Interface::*Callback)(void *data);

class Interface
{
    public:
        std::function<void(void*)> register;

            Interface(std::function<void(void*)> register_)
            :    register(register_)   //intializer list
            {}
            virtual ~Interface(){} //put me in
};

void Interface::Register(Callback func)
{
    std::cout << "Register" << std::endl;
}


class B : public Interface
{
    public:
        B();
        void Echo(void *data);
};

B::B()
:   Interface( std::bind(B::Echo, this) )
{}

void B::Echo(void *data)
{
    std::cout << "Echo" << std::endl;
}
class Interface
{
    public:
        virtual void Echo(void*)=0;

};

void B::Echo(void *data) //implements Echo
{
    std::cout << "Echo" << std::endl;
}
class Interface
{
public:
    virtual ~Interface(){} //put me in
    virtual void echo(void*){}  //if implementation is not extended it will do nothing.
    //others 
};
template <class T> class Interface {
public:
    typedef void (T::*Callback)(void *data);
    void Register(Callback func) {
        std::cout << "Register" << std::endl;
    }
    // ...
};

class B : public Interface<B> {
public:
    B() {
        Register(&B::Echo);
    }
    void Echo(void *data) {
        // Do something
    }
};