2017-08-10 96 views
1

我有以下代码使用多重继承。目的是在派生类使用两个接口,一个:哪个基类调用派生重写方法?

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

注册的界面会造成on_state_changed的异步调用。是否有可能辨别哪个接口正在调用它?

+1

如果你需要这些信息,为什么不添加一个参数来告诉你你需要什么? –

+1

或者干脆不要使用多重继承。 – Ron

+0

我觉得这个[文章](http://www.cprogramming.com/tutorial/multiple_inheritance.html)在陷阱小标题下有一些这方面的信息。 – Mekicha

回答

5

您必须在中间添加一层来消除歧义。这里有一个小实用程序,可以即时创建它们:

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

就是这样。然后,它在此实用程序来定义你的类的问题:

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

我用另一个参数和重载,使这个模板化,但该技术本身也可以通过写班列和调用来完成具有新名称的虚拟功能。关键是使原始虚拟调用(通过接口指针)达到调用消歧函数的短暂调用。

0

我正在考虑使用模板来消除歧义,但我相信@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 
    } 
}; 
2

或者,也可以直接在源性的代码提供处理程序单独实施:

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++编译器的非标准和支持。

+0

这不是为我编译的。你正在使用哪个编译器+版本? – nyarlathotep108

+0

它是VS 2010.它应该是经典的C++。你遇到了什么错误? – jszpilewski

+0

错误:无法在Derived中定义成员函数'InterfaceA :: on_state_changed' void InterfaceA :: on_state_changed(const State state)覆盖{} ^ – nyarlathotep108

相关问题