C++ 哪个基类正在调用派生的重写方法?

C++ 哪个基类正在调用派生的重写方法?,c++,overriding,multiple-inheritance,C++,Overriding,Multiple Inheritance,我有以下使用多重继承的代码。其目的是将两个接口用作派生类中的一个接口: struct InterfaceA { virtual void register_stuff(); virtual void on_state_changed( const State state ) = 0; }; struct InterfaceB { virtual void register_stuff(); virtual void on_state_changed( const

我有以下使用多重继承的代码。其目的是将两个接口用作派生类中的一个接口:

struct InterfaceA
{
    virtual void register_stuff();
    virtual void on_state_changed( const State state ) = 0;
};

struct InterfaceB
{
    virtual void register_stuff();
    virtual void on_state_changed( const State state ) = 0;
};

struct Derived : InterfaceA, InterfaceB
{
    void register_stuff() override
    {
        InterfaceA::register_stuff();
        InterfaceB::register_stuff();
    }

    void on_state_changed( const State state ) override
    {
        // how can I know who is responding?
    }
};

注册接口将导致在状态更改时对
进行异步调用。有没有可能分辨出调用它的是哪个接口?

您必须在两者之间添加一个层来消除歧义。下面是一个小实用程序,它可以动态创建这些功能:

template<class Inteface>
struct disambiguate : Interface {
  void on_state_changed( const State state ) override final {
    on_state_changed(state, this);
  }
  virtual void on_state_changed( const State &state, disambiguate* ) = 0;
};
模板
结构消歧:接口{
无效状态更改(常量状态)覆盖最终{
on_状态_已更改(状态,此);
}
更改状态上的虚拟无效(常量状态和状态,消除歧义*)=0;
};
就这样。然后就需要根据这个实用程序定义类:

struct Derived : disambiguate<InterfaceA>, disambiguate<InterfaceB>
{
    void register_stuff() override
    {
        InterfaceA::register_stuff();
        InterfaceB::register_stuff();
    }

    void on_state_changed( const State &state, disambiguate<InterfaceA>* ) override
    {
        // Called for A
    }

    void on_state_changed( const State &state, disambiguate<InterfaceB>* ) override
    {
        // Called for B
    }
};
struct派生:消歧,消歧
{
无效寄存器\u stuff()重写
{
InterfaceA::register_stuff();
InterfaceB::register_stuff();
}
更改状态时无效(常量状态和状态,消除歧义*)覆盖
{
//要求
}
更改状态时无效(常量状态和状态,消除歧义*)覆盖
{
//叫B
}
};

我使用了另一个参数和重载来将其模板化,但该技术本身也可以通过编写类并使用新名称调用虚拟函数来实现。关键是使原始虚拟调用(通过接口指针)达到调用消歧函数的短thunk

您必须在中间添加一层来消除歧义。下面是一个小实用程序,它可以动态创建这些功能:

template<class Inteface>
struct disambiguate : Interface {
  void on_state_changed( const State state ) override final {
    on_state_changed(state, this);
  }
  virtual void on_state_changed( const State &state, disambiguate* ) = 0;
};
模板
结构消歧:接口{
无效状态更改(常量状态)覆盖最终{
on_状态_已更改(状态,此);
}
更改状态上的虚拟无效(常量状态和状态,消除歧义*)=0;
};
就这样。然后就需要根据这个实用程序定义类:

struct Derived : disambiguate<InterfaceA>, disambiguate<InterfaceB>
{
    void register_stuff() override
    {
        InterfaceA::register_stuff();
        InterfaceB::register_stuff();
    }

    void on_state_changed( const State &state, disambiguate<InterfaceA>* ) override
    {
        // Called for A
    }

    void on_state_changed( const State &state, disambiguate<InterfaceB>* ) override
    {
        // Called for B
    }
};
struct派生:消歧,消歧
{
无效寄存器\u stuff()重写
{
InterfaceA::register_stuff();
InterfaceB::register_stuff();
}
更改状态时无效(常量状态和状态,消除歧义*)覆盖
{
//要求
}
更改状态时无效(常量状态和状态,消除歧义*)覆盖
{
//叫B
}
};

我使用了另一个参数和重载来将其模板化,但该技术本身也可以通过编写类并使用新名称调用虚拟函数来实现。关键是使原始虚拟调用(通过接口指针)达到调用消歧函数的短thunk

我也在考虑使用模板来消除歧义,但我相信@StoryTeller的答案更优雅

struct InterfaceA
{
    virtual void register_stuff();  // calls on_state_changed<InterfaceA>()

    template <typename Interface>
    virtual void on_state_changed( const State state ) = 0;
};

struct InterfaceB
{
    virtual void register_stuff();  // calls on_state_changed<InterfaceB>()

    template <typename Interface>
    virtual void on_state_changed( const State state ) = 0;
};

struct Derived : InterfaceA, InterfaceB
{
    void register_stuff() override
    {
        InterfaceA::register_stuff();
        InterfaceB::register_stuff();
    }

    template <typename Interface>
    void on_state_changed( const State state ) override
    {
        // how can I know who is responding?
        // : "Interface" is responding
    }
};
struct接口a
{
virtual void register_stuff();//对_state_changed()的调用
模板
_状态_更改时的虚拟无效(const state state)=0;
};
结构接口B
{
virtual void register_stuff();//对_state_changed()的调用
模板
_状态_更改时的虚拟无效(const state state)=0;
};
结构派生:接口A、接口B
{
无效寄存器\u stuff()重写
{
InterfaceA::register_stuff();
InterfaceB::register_stuff();
}
模板
更改状态时无效(常量状态)覆盖
{
//我怎么知道谁在回应?
//:“接口”正在响应
}
};

我也在考虑使用模板来消除歧义,但我相信@StoryTeller的答案更优雅

struct InterfaceA
{
    virtual void register_stuff();  // calls on_state_changed<InterfaceA>()

    template <typename Interface>
    virtual void on_state_changed( const State state ) = 0;
};

struct InterfaceB
{
    virtual void register_stuff();  // calls on_state_changed<InterfaceB>()

    template <typename Interface>
    virtual void on_state_changed( const State state ) = 0;
};

struct Derived : InterfaceA, InterfaceB
{
    void register_stuff() override
    {
        InterfaceA::register_stuff();
        InterfaceB::register_stuff();
    }

    template <typename Interface>
    void on_state_changed( const State state ) override
    {
        // how can I know who is responding?
        // : "Interface" is responding
    }
};
struct接口a
{
virtual void register_stuff();//对_state_changed()的调用
模板
_状态_更改时的虚拟无效(const state state)=0;
};
结构接口B
{
virtual void register_stuff();//对_state_changed()的调用
模板
_状态_更改时的虚拟无效(const state state)=0;
};
结构派生:接口A、接口B
{
无效寄存器\u stuff()重写
{
InterfaceA::register_stuff();
InterfaceB::register_stuff();
}
模板
更改状态时无效(常量状态)覆盖
{
//我怎么知道谁在回应?
//:“接口”正在响应
}
};

或者,可以直接在派生代码中为处理程序提供单独的实现:

    struct Derived : InterfaceA, InterfaceB
     {
        void register_stuff() override
        {
            InterfaceA::register_stuff();
            InterfaceB::register_stuff();
        }

        void InterfaceA::on_state_changed( const State state ) override
        {
            // responding A
        }

        void InterfaceB::on_state_changed( const State state ) override
        {
            // responding B        
        }
  };

<>编辑:不幸的是,这个解决方案是非标准的,只支持VisualC++编译器。

< P>可在派生代码中直接提供处理程序的单独实现:

    struct Derived : InterfaceA, InterfaceB
     {
        void register_stuff() override
        {
            InterfaceA::register_stuff();
            InterfaceB::register_stuff();
        }

        void InterfaceA::on_state_changed( const State state ) override
        {
            // responding A
        }

        void InterfaceB::on_state_changed( const State state ) override
        {
            // responding B        
        }
  };

<>编辑:不幸的是,这个解决方案是非标准的,只支持Visual C++编译器。为什么不添加一个参数来告诉您需要什么?或者干脆不要使用多重继承。我想这在陷阱子标题下有一些关于这方面的信息。@Boperson我无法修改接口:这些接口来自lib@Ron答案是“没有办法知道”吗?如果你需要信息,为什么不添加一个参数来告诉您需要什么?或者干脆不要使用多重继承。我想这在陷阱子标题下有一些关于这方面的信息。@Boperson我无法修改接口:这些接口来自lib@Ron答案是“没有办法知道它”吗?这不是为我编写的。您使用的是哪个编译器+版本?它是VS2010。它应该是经典C++。您遇到了什么错误?错误:无法在“派生”void interfaceea::on_state_changed(const state state)override{}^中定义成员函数“interfaceea::on_state_changed”,这有点酷。是否有人在C++中推动它?这对我来说不是编译。您使用的是哪个编译器+版本?它是VS2010。它应该是经典C++。您遇到了什么错误?错误:无法在“派生”void InterfaceA::on_state_changed(const state state)ov中定义成员函数“InterfaceA::on_state_changed”