2

我有两个类AB,两个定义方法m()。虽然这些方法的签名是相同的,但它们是两种完全不同的方法,具有不同的含义。在课堂C中,我想更新m()。而不是写在类C中的新m(),从AB熔合两个m(),我想分开重写它们。请看下面的代码:我可以在C++中使用/模仿一些类似于(部分覆盖)的东西吗?

class A { public: virtual void m() {cout << "MA" << endl;}}; 
class B { public: virtual void m() {cout << "MB" << endl;}}; 
class C : public A, public B { 
    public: virtual void m() update A {cout << "MA2" << endl;}}; 
    public: virtual void m() update B {cout << "MB2" << endl;}}; 
} 
void func(A* a) { a->m(); } 
int main() { 
    C* c = new C(); 
    c->B::m();  //print "MB2" 
    func(c);   //print "MA2" 
    return 0; 
} 

我知道update语法不是C++的支持,但没有任何解决方法在C++模拟这个?

+0

从[本问答](https://stackoverflow.com/questions/18398409/c-inherit-from-multiple-base-classes-with-the-same-virtual-function-name)看起来像你一样运气不好。不知道它是否应该作为一个愚蠢的关闭。 – NathanOliver

+0

'c-> B :: m();''会**总是**调用'B :: m()'而不动态分派。你的例子应该转换为'B *'。 – StoryTeller

+0

是的你是对的,在C++中,::是静态查找。然而,即使我使用“B *”,我想在C++中仍然没有办法像我描述的那样定义方法“update”? –

回答

2

多继承的一个令人讨厌的部分是确实只有一个mC覆盖两个。如果有两个或更多类定义m,您需要一个中间人类来消除呼叫。幸运的是,你可以用一个模板,以流程自动化:

template<class C> 
class MiddleMan : public C { 
    void m() override final { m_impl(this); } 
protected: 
    virtual void m_impl(MiddleMan*) = 0; 
}; 

现在,你只需要使用这个模板,并重写新的功能就补充道:

class C : public MiddleMan<A>, public MiddleMan<B> { 
    private: 
    void m_impl (MiddleMan<A>*) override {cout << "MA2" << endl;} 
    void m_impl (MiddleMan<B>*) override {cout << "MA2" << endl;} 
}; 

m每个中间人实施类将调用超载的新虚函数。然后定义这些重载。我使用MiddleMan*作为促进重载的额外参数,但任何便宜的值传递并取决于模板参数的类型都可用于消除歧义。

相关问题