如何在派生类中重用基类函数

发布于 2024-10-10 20:30:45 字数 752 浏览 1 评论 0 原文

假设我们有这四个类:

  • 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。

那么,我该怎么做呢?

编辑:

纠正了一些错误并重构了问题,我希望现在更清楚了。

Let's say we have these four classes:

  • BinaryTree,
  • SplayTree (which is a sub-class of BinaryTree),
  • BinaryNode and
  • SplayNode (which is a sub-class of BinaryNode).

In class BinaryTree I have these 2 functions, and in SplayTree I would like to reuse the first one, because it works in the same way as in 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
{
    //...
}

Now, the problem is when I have an instance of SplayTree and I call Find, the Binary::Find2 is called instead of SplayTree::Find2, which is what I want.

So, how can I do this?

EDIT:

Corrected some mistakes and refactored the quetion, I hope it's clearer now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你与清晨阳光 2024-10-17 20:30:45

CRTP 习惯用法用于解决此类问题。基本上,您从一个模板派生,该模板获取派生类作为模板参数,因此您可以在返回值等中使用该类型。

在您的实例中,您需要为两种树类型创建一个公共基本模板并实现您的在那里Find,同时在派生类中实现Find2

template <class T> class BaseTree
{
public:
  bool Find()
  {
    typename T::NodeType* NodePtr = static_cast<T*>(this)->Find2(...);
  }
}

template <class T>
class BinaryTree<T> : public BaseTree<BinaryTree<T>>
{
public:
  typedef Node<T> NodeType;
  NodeType Find2(); // will be called from BaseTree
};

template <class T>
class SplayTree : public BaseTree<SplayTree<T>>
{
  typedef SplayNode<T> NodeType;
  NodeType Find2(); // dito
};

这基本上实现了“静态多态性”。相对于普通多态性的好处是您可以根据需要使用返回类型。

编辑:添加了更详细的描述以更好地适合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 implementing Find2 in the derived classes:

template <class T> class BaseTree
{
public:
  bool Find()
  {
    typename T::NodeType* NodePtr = static_cast<T*>(this)->Find2(...);
  }
}

template <class T>
class BinaryTree<T> : public BaseTree<BinaryTree<T>>
{
public:
  typedef Node<T> NodeType;
  NodeType Find2(); // will be called from BaseTree
};

template <class T>
class SplayTree : public BaseTree<SplayTree<T>>
{
  typedef SplayNode<T> NodeType;
  NodeType Find2(); // dito
};

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.

梦里寻她 2024-10-17 20:30:45

您面临的问题是 SplayTree::Find2 不是 BinaryTree::Find2 的重写,而是一个不同的重载(同时隐藏了原始函数) )。它是一个不同函数的原因是 C++ 支持协变返回类型,但不支持方法参数,因此

BinaryTree 级别,对 Find2 的调用需要Node 类型的参数,此类方法的唯一重写是 BinaryTree::Find2。如果您希望将方法调用分派到最派生的类型,则必须重写该方法,即在最派生的类中提供具有相同签名的方法。

The problem you are facing is that SplayTree::Find2 is not an override of BinaryTree::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 thus

At the BinaryTree level the call to Find2 takes an argument of type Node<T>, and the only override for such a method is BinaryTree::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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文