如何在派生类中重用基类函数
假设我们有这四个类:
- BinaryTree、
- SplayTree(BinaryTree 的子类)、
- BinaryNode 和
- SplayNode(BinaryNode 的子类)。
在 BinaryTree 类中,我有这两个函数,在 SplayTree 中,我想重用第一个函数,因为它的工作方式与 SplayTree 中的相同。
//BinaryTree.cpp
bool Find(const T &data) const
{
Node<T> *found = Find2(data, root);
//...
}
virtual Node<T> * Find2(const T &data, Node<T> *node) const
{
//...
}
//SplayTree.cpp
using BinaryTree::Find;
virtual SplayNode<T> * Find2(const T &data, SplayNode<T> *node) const
{
//...
}
现在,问题是当我有一个 SplayTree 实例并调用 Find 时,会调用 Binary::Find2 而不是我想要的 SplayTree::Find2。
那么,我该怎么做呢?
编辑:
纠正了一些错误并重构了问题,我希望现在更清楚了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
CRTP 习惯用法用于解决此类问题。基本上,您从一个模板派生,该模板获取派生类作为模板参数,因此您可以在返回值等中使用该类型。
在您的实例中,您需要为两种树类型创建一个公共基本模板并实现您的在那里
Find
,同时在派生类中实现Find2
:这基本上实现了“静态多态性”。相对于普通多态性的好处是您可以根据需要使用返回类型。
编辑:添加了更详细的描述以更好地适合OP。
The CRTP idiom is used to solve problems like this. Basically, you derive from a template that gets the derived class as a template parameter, so you can use the type in return values etc.
In your instance, you need to create a common base-template for the two tree-types and implement your
Find
there, while implementingFind2
in the derived classes:This basically implements 'static polymorphism'. The benefit against normal polymorphism is that you can use return types as you'd like.
Edit: Added more detailed description to better suit the OP.
您面临的问题是
SplayTree::Find2
不是BinaryTree::Find2
的重写,而是一个不同的重载(同时隐藏了原始函数) )。它是一个不同函数的原因是 C++ 支持协变返回类型,但不支持方法参数,因此在
BinaryTree
级别,对Find2
的调用需要Node
类型的参数,此类方法的唯一重写是BinaryTree::Find2
。如果您希望将方法调用分派到最派生的类型,则必须重写该方法,即在最派生的类中提供具有相同签名的方法。The problem you are facing is that
SplayTree::Find2
is not an override ofBinaryTree::Find2
, but rather a different overload (that at the same time hides the original function). The reason why it is a different function is that C++ has support for covariant return types, but not arguments to methods, and thusAt the
BinaryTree
level the call toFind2
takes an argument of typeNode<T>
, and the only override for such a method isBinaryTree::Find2
. If you want the method call to be dispatched to the most derived type, you have to override the method, that is provide a method with the same exact signature in the most derived class.