如何重写另一个基类中的函数? [英] How to override a function in another base class?
问题描述
我不确定要使用的术语,但这是我的示例:
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;
^
有可能这样做吗?
我知道一种选择是使Mixin
从Base
继承,但是在我的情况下,有几个派生类,并且它们没有相同的祖先.
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
继承说明符来避免歧义,并且与以前的方法不同-我们将不会颠倒Mixin
和Example
类的继承顺序.
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屋!