Как я могу повторно использовать функцию базового класса в производном классе - PullRequest
4 голосов
/ 08 января 2011

Допустим, у нас есть эти четыре класса:

  • BinaryTree,
  • 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, что я и хочу.

Итак, как я могу это сделать?

EDIT:

Исправлены некоторые ошибки и реорганизован вопрос, надеюсь, теперь он понятнее.

Ответы [ 2 ]

4 голосов
/ 08 января 2011

Идиома 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
};

Это в основном реализует «статический полиморфизм». Преимущество обычного полиморфизма заключается в том, что вы можете использовать возвращаемые типы по своему усмотрению.

Редактировать: Добавлено более подробное описание для лучшего соответствия ОП.

2 голосов
/ 08 января 2011

Проблема, с которой вы сталкиваетесь, заключается в том, что SplayTree::Find2 - это не переопределение BinaryTree::Find2, а скорее перегрузка (которая в то же время скрывает исходную функцию).Причина, по которой это другая функция, заключается в том, что в C ++ есть поддержка ковариантных возвращаемых типов, но не аргументов для методов, и поэтому

На уровне BinaryTree вызов Find2 принимает аргумент типа Node<T>, и единственным переопределением для такого метода является BinaryTree::Find2.Если вы хотите, чтобы вызов метода передавался наиболее производному типу, необходимо переопределить метод, то есть предоставить метод с той же точной сигнатурой в наиболее производном классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...