假设我们有这四个类:

  • 二叉树,
  • SplayTree(它是 BinaryTree 的子类),
  • BinaryNode 和
  • SplayNode(它是 BinaryNode 的子类)。

  • 在 BinaryTree 类中,我有这 2 个函数,而在 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,这正是我想要的。

    那么,我该怎么做呢?

    编辑:

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

    最佳答案

    CRTP 习语用于解决此类问题。基本上,您从一个模板派生,该模板将派生类作为模板参数,因此您可以在返回值等中使用该类型。
    在您的实例中,您需要为两种树类型创建一个公共(public)基础模板并在那里实现您的 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。

    关于c++ - 如何在派生类中重用基类函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4634295/

    10-11 18:32