Как получить абстрактные классы шаблонов с типами шаблонов в качестве параметров функции (C++11)

Мне поручили написать класс «binaryExpressionTree», который является производным от класса абстрактного шаблона «binaryTreeType». binaryExpressionTree имеет тип String. В рамках задания я должен переопределить эти 3 виртуальные функции из binaryTreeType:

//Header File Binary Search Tree
#ifndef H_binaryTree
#define H_binaryTree

#include <iostream>

using namespace std;

//Definition of the Node
template <class elemType>
struct nodeType
{
    elemType info;
    nodeType<elemType> *lLink;
    nodeType<elemType> *rLink;
};

//Definition of the class
template <class elemType>
class binaryTreeType
{
public:
virtual bool search(const elemType& searchItem) const = 0;


    virtual void insert(const elemType& insertItem) = 0;


    virtual void deleteNode(const elemType& deleteItem) = 0;

    binaryTreeType();
    //Default constructor
};

binaryTreeType<elemType>::binaryTreeType()
{
}

#endif

Вот что у меня есть для binaryExpressionTree:

#define EXPRESSIONTREE_H

#include "binaryTree.h" 

#include <iostream>
#include <string>
class binaryExpressionTree : public binaryTreeType<string> {

  public:

  void buildExpressionTree(string buildExpression);

  double evaluateExpressionTree();

  bool search(const string& searchItem) const = 0;

    void insert(const string& insertItem) = 0;

    void deleteNode(const string& deleteItem) = 0;
};

А вот бинарноеExpressionTree.cpp:

#include <string>
#include <cstring>
#include <stack>
#include <cstdlib>
#include <cctype>
#include "binaryExpressionTree.h"
#include "binaryTree.h"

using namespace std;

bool binaryExpressionTree::search(const string& searchItem) const {
    return false;
  }

  void binaryExpressionTree::insert(const string& insertItem) {
    cout << "this";
  }

  void binaryExpressionTree::deleteNode(const string& deleteItem) {
    cout << "this";
  }

Вот main.cpp:

#include <iostream>
#include <iomanip>
#include <fstream>
#include "binaryExpressionTree.h"

int main() 
{
binaryExpressionTree mainTree = binaryExpressionTree(); //Error:[cquery] allocating an object of abstract class type 'binaryExpressionTree'
return 0;
}

Проблема в том, что, поскольку binaryExpressionTree является производным классом типа String, он не знает, что означает «elemType», и мне нужно было бы изменить searchItem, insertItem and deleteItem на строку и объекты. Но как только я это делаю, компилятор больше не распознает, что я переопределяю виртуальные функции (поскольку я изменил их параметры), и объявляет binaryExpressionTree абстрактным классом. Как мне обойти это, чтобы я мог переопределить функции и сделать binaryExpressionTree неабстрактным?


person Ian Crovella    schedule 07.12.2019    source источник
comment
Привет. Пожалуйста, предоставьте минимальный воспроизводимый пример. То есть то, что я могу скомпилировать, не добавляя ничего дополнительного.   -  person iliar    schedule 08.12.2019
comment
Хорошая точка зрения. Я только что добавил это в   -  person Ian Crovella    schedule 08.12.2019


Ответы (1)


Предполагая, что абстрактный класс определен следующим образом:

template <typename elemType>
class binaryTreeType { ... }

Вы должны определить свой класс следующим образом:

class binaryExpressionTree : public binaryTreeType<String> { ... }

РЕДАКТИРОВАТЬ: исходный вопрос был отредактирован.

Вы неправильно объявляете переопределяющие функции (внутри binaryExpressionTree). Ваша декларация выглядит так:

bool search(const string& searchItem) const = 0;

Такое объявление создает чисто виртуальный метод (из-за = 0 в конце объявления. Чисто виртуальный метод (также известный как абстрактный метод) — это метод, который должен быть переопределен производным классом. Таким образом, binaryTreeType объявил свои методы чисто виртуальными, в приказ вам реализовать в binaryExpressionTree.

Классы с абстрактными методами, которые еще не реализованы, не могут быть созданы - это ошибка, которую генерирует ваш компилятор.

Вместо этого вы должны объявить свои методы следующим образом:

virtual bool search(const elemType& searchItem) const;

Такое объявление создает обычную виртуальную функцию, которая переопределяет родительскую реализацию (которой в данном случае не существует).

TL;DR - удалить = 0.

person OSteiner    schedule 07.12.2019
comment
Я сделал, хотя это ‹string›, так как я использую #include ‹string› из библиотеки. - person Ian Crovella; 07.12.2019
comment
Мне понадобится более сложный фрагмент кода обоих классов, чтобы понять проблему. - person OSteiner; 08.12.2019
comment
Извините за отсутствие информации, я новичок в этом деле. Я только что обновил вопрос, указав достаточно кода для компиляции. - person Ian Crovella; 08.12.2019