Search code examples
c++11templatesabstract-classvirtual-functionstemplate-classes

How to derive abstract template classes, with template-types as function parameters (C++11)


I've been assigned to write a class "binaryExpressionTree" which is derived from the abstract template class "binaryTreeType." binaryExpressionTree is of type String. As part of the assignment, I have to override these 3 virtual functions from 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

Here is what I have so far for 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;
};

And here's binaryExpressionTree.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";
  }

Here's 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;
}

The problem is, since binaryExpressionTree is a derived class of type String, it doesn't know what "elemType" means and I would need to change searchItem, insertItem and deleteItem to string& objects. But once I do, the compiler no longer recognizes that I am overriding virtual functions (as I've changed their parameters), and declares binaryExpressionTree to be an abstract class. How do I work around this, so that I can override the functions and make binaryExpressionTree non-abstract?


Solution

  • Assuming the abstract class is defined like this:

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

    You should define your class as follows:

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

    EDIT: original question was edited.

    You are incorrectly declaring the overriding functions (inside binaryExpressionTree). Your declaration is like this:

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

    Such declaration creates a pure virtual method (because of = 0 at the end of the declaration. A pure virtual method (aka an abstract method) is a method which must be overridden by a deriving class. Thus, binaryTreeType declared its methods pure virtual, in order for you to implement, in binaryExpressionTree.

    Classes which have abstract methods which are not implemented yet, cannot be instantiated - that is the error your compiler is generating.

    Instead, you should declare your methods like this:

    virtual bool search(const elemType& searchItem) const;
    

    Such declaration creates regular virtual function, which would override the parent implementation (which is non-existent, at this case).

    TL;DR - remove = 0.