如何重写另一个基类中的函数? [英] How to override a function in another base class?

查看:168
本文介绍了如何重写另一个基类中的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定要使用的术语,但这是我的示例:

I'm not exactly sure the terminology to use, but here's my example:

class Base {
public:
    virtual void test() = 0;
};

class Mixin {
public:
    virtual void test() { }
};

class Example : public Base, public Mixin {
};

int main(int argc, char** argv) {
    Example example;
    example.test();
    return 0;
}

我希望我的Mixin类实现纯虚函数Base::test,但是当我编译它时,它说:

I want my Mixin class to implement the pure virtual function Base::test, but when I compile this, it says:

test.cpp: In function ‘int main(int, char**)’:
test.cpp:15:13: error: cannot declare variable ‘example’ to be of abstract type ‘Example’
     Example example;
             ^
test.cpp:11:7: note:   because the following virtual functions are pure within ‘Example’:
 class Example : public Base, public Mixin {
       ^
test.cpp:3:18: note:    virtual void Base::test()
     virtual void test() = 0;
                  ^
test.cpp:16:13: error: request for member ‘test’ is ambiguous
     example.test();
             ^
test.cpp:8:18: note: candidates are: virtual void Mixin::test()
     virtual void test() { }
                  ^
test.cpp:3:18: note:                 virtual void Base::test()
     virtual void test() = 0;
                  ^

我可以添加一个using语句以使其不模糊:

I can add a using statement to make it not ambiguous:

class Example : public Base, public Mixin {
public:
    using Mixin::test;
};

但是它说我还没有实现它:

But it says I still haven't implemented it:

test.cpp: In function ‘int main(int, char**)’:
test.cpp:17:13: error: cannot declare variable ‘example’ to be of abstract type ‘Example’
     Example example;
             ^
test.cpp:11:7: note:   because the following virtual functions are pure within ‘Example’:
 class Example : public Base, public Mixin {
       ^
test.cpp:3:18: note:    virtual void Base::test()
     virtual void test() = 0;
                  ^

有可能这样做吗?

我知道一种选择是使MixinBase继承,但是在我的情况下,有几个派生类,并且它们没有相同的祖先.

I know one option is to make Mixin inherit from Base, but in my case there's several derived classes and they don't share a common ancestor.

推荐答案

您不能直接 让一个类覆盖其基类以外的方法.但是您可以通过回旋方式来完成.我将介绍两种这样的方法-我更喜欢第二种.

You cannot directly have a class override a method not of its base class. But you can sort-of of do it in a roundabout way. I'll present two such approaches - I prefer the second.

Daniel Paul在 thinkbottomup.com.au 上的帖子中对此进行了描述,标题为 C ++ Mixins-通过继承进行重用是很好的……只要以正确的方式进行操作.

This is described by Daniel Paul in a post on thinkbottomup.com.au, entitled C++ Mixins - Reuse through inheritance is good... when done the right way.

您的情况如下所示:

class Base {
public:
    virtual void test() = 0;
};

template <typename T>
class Mixin : public T {
public:
    virtual void test() override { /*... do stuff ... */ }
};

class UnmixedExample : public Base {
    /* definitions specific to the Example class _not_including_
       a definition of the test() method */
};

using Example = class Mixin<UnmixedExample>;

int main(int argc, char** argv) {
    Example{}.test();
    return 0;
}

方法2:CRTP!

CRTP 是好奇地重复使用的模板模式"-如果您以前从未看过它,请务必遵循该链接.通过这种方法,我们将使用virtual继承说明符来避免歧义,并且与以前的方法不同-我们将不会颠倒MixinExample类的继承顺序.

Approach 2: CRTP!

CRTP is the "Curiously Recurring Template Pattern" - definitely follow that link if you haven't seen it before. With this approach, we'll be using the virtual inheritance specifier to avoid ambiguity, and unlike the previous approach - we will not be reversing the inheritance order of the Mixin and Example classes.

class Base {
public:
    virtual void test() = 0;
};

template <typename T>
class Mixin : virtual T {
public:
    virtual void test() override { /*... do stuff ... */ }
};

class Example : public virtual Base, public virtual Mixin<Base> {
    /* definitions specific to the Example class _not_including_
       a definition of the test() method */
};

int main(int argc, char** argv) {
    Example{}.test();
    return 0;
}

关于这两种解决方案的说明:

Note about both solutions:

  • 您是否对CRTP如何在各地重复出现感到好奇? :-)
  • 出于教学目的,我使用的代码是C ++ 11,但在C ++ 98中也可以使用.

这篇关于如何重写另一个基类中的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆