通过CRTP基类覆盖虚函数
Override virtual function through CRTP base class
Old:如何通过CRTP基类重写虚函数?
struct I { virtual void foo() = 0; };
template<class D>
struct B { void foo() { } }; // provides implementation of foo in D
struct D : I, B<D> { }; // D has an implementation of foo that should override I
int main() { D d; }
Error: unimplemented pure virtual method 'foo' in 'D'
更简单:如何重写虚函数而不用在派生类型中重新实现它?(我想这个问题违背了虚函数的定义)
struct I { virtual void foo() = 0; };
struct B { void foo() { } };
struct D : B, I { };
int main() { D d; }
除了明显但笨拙的void foo() { B::foo(); }
解决方案之外,您还可以将"实现foo
"接口与更完整的接口I
分开:
struct FooInterface {
virtual ~FooInterface() {}
virtual void foo() = 0;
};
struct I : public virtual FooInterface {};
template<class D>
struct B : public virtual FooInterface { void foo() { } };
struct D : I, B<D> {};
int main() { D d; }
您可以将D::foo()
实现为调用B<D>::foo()
的简单包装器。如果你有很多地方需要这样做,你可以做一个宏来帮助,像:
#define WRAP(CLASS, METHOD)
METHOD() { return CLASS::METHOD(); }
struct D : I, B<D>
{
void WRAP(B<D>, foo);
};
您不必要地混合了两个不同的概念:crtp和继承虚函数的实现
crtp用于编译时多态性,虚函数用于运行时多态性
也就是说,您可以通过在虚拟继承层次结构中支配的方式继承虚函数的实现,这大致产生java/c#实现继承 的效果。的例子:
struct tutti_i
{
virtual int frutti() const = 0;
};
struct tutti_impl_1
: virtual tutti_i
{
int frutti() const override { return 42; }
};
struct base
: virtual tutti_i
{};
struct derived
: base
, tutti_impl_1
{};
#include <iostream>
int main()
{
tutti_i&& tutti = derived();
std::cout << tutti.frutti() << std::endl;
}
对于那些不关心B是否从I继承的人,您也可以像最初要求的那样使用CRTP实现这一点:
struct I { virtual void foo() = 0; };
template <class D>
struct B : I { void foo(){ /* Do something fancy with D's type */ } };
struct D : B<D> { };
如果您需要进一步继承,以便foo的实现始终是派生最多的类型,您可以引入一个中间类型来消除使用哪个foo实现的歧义:
struct I { virtual void foo() = 0; };
template <class T>
struct B : virtual I { void foo() { /* Do something fancy with the most-derived type */ }};
struct D : B<D> { };
template <typename Base, typename Derived>
struct InheritFrom : public Base, public B<D> { void foo() { B<D>::foo(); } };
struct FurtherDerived : InheritFrom<D, FurtherDerived> { };
相关文章:
- 使用可变参数函数覆盖具有不同函数签名的虚函数
- 如何使用用户定义的函数覆盖 C lib 函数,如 _sbrk?
- 函数覆盖有哪些用例?
- 在子类函数覆盖中省略具有默认值的参数
- C++ 成员变量被非成员函数覆盖
- 用现有函数覆盖虚拟函数
- 函数覆盖是否由编译器自动完成
- 结构被库函数覆盖
- 当在Python中定义__str__时,如何将C 的标准全局函数覆盖
- C++类是否解决函数覆盖问题
- 用私有基函数覆盖公共虚拟函数
- 优先级队列中复制构造函数覆盖的值
- 虚拟函数覆盖预期错误
- C++中的函数覆盖无需"虚拟"即可工作
- C++虚拟函数覆盖
- 如何用非虚拟函数覆盖虚拟函数
- 基成员函数的所有重载是否可以被单个模板化成员函数覆盖和转发到
- C++继承函数覆盖
- 纯虚函数覆盖虚函数
- 引用项目的Qt-main()函数覆盖实际项目的main()