简体   繁体   中英

Inheritance with template classes and interfaces

Goal: Implement queue. Problem: Unable to instantiate "OurQueue" class *note: class "OurQueue" is also supposed to have:

queue();                // Default constructor
bool empty() const ;             // Tests whether the queue is empty
void push(const ItemType& newEntry);    // Adds newEntry to the back of the queue
void pop();                 // Removes the front of the queue
ItemType& front();          // Returns a reference to the front of the queue

(but I can't even instantiate it so I haven't added these)

Interface:

/** @file QueueInterface.h */

#ifndef _QUEUE_INTERFACE
#define _QUEUE_INTERFACE

template<class ItemType>
class QueueInterface

{
public:
   /** Sees whether this queue is empty.
    @return True if the queue is empty, or false if not. */
   virtual bool isEmpty() const = 0;

   /** Adds a new entry to the back of this queue.
    @post If the operation was successful, newEntry is at the 
       back of the queue.
    @param newEntry  The object to be added as a new entry.
    @return True if the addition is successful or false if not. */
   virtual bool enqueue(const ItemType& newEntry) = 0;

   /** Removes the front of this queue.
    @post If the operation was successful, the front of the queue 
       has been removed.
    @return True if the removal is successful or false if not. */
   virtual bool dequeue() = 0;

   /** Returns the front of this queue.
    @pre The queue is not empty.
    @post The front of the queue has been returned, and the
       queue is unchanged.
    @return The front of the queue. */
   virtual ItemType peekFront() const = 0;
   virtual ~QueueInterface(){};
}; // end QueueInterface
#endif

ArrayQueue header file

    /** ADT queue: Circular array-based implementation.
 @file ArrayQueue.h */

#ifndef _ARRAY_QUEUE
#define _ARRAY_QUEUE

#include "QueueInterface.h"
#include "PrecondViolatedExcep.h"
#include "ArrayQueue.cpp"

const int MAX_QUEUE = 50;

template<class ItemType>
class ArrayQueue : public QueueInterface<ItemType>
{
private:
   ItemType items[MAX_QUEUE]; // Array of queue items
   int front;                 // Index to front of queue
   int back;                  // Index to back of queue
   int count;                 // Number of items currently in the queue

public:
   ArrayQueue();   
   // Copy constructor and destructor supplied by compiler

   bool isEmpty() const;
   bool enqueue(const ItemType& newEntry);
   bool dequeue();

   /** @throw PrecondViolatedExcep if queue is empty. */
   ItemType peekFront() const throw(PrecondViolatedExcep);
}; // end ArrayQueue
#endif

OurQueue class implementation and main file

#include <queue>
#include <iostream>
#include <string>

#include "QueueInterface.h"
#include "ArrayQueue.h"
#include "PrecondViolatedExcep.h"

using namespace std;


template<class ItemType>
class OurQueue : public ArrayQueue<ItemType> {
    OurQueue(){};               // Default constructor
};


int main() {

    QueueInterface<int>*listPtr = new ArrayQueue<int>(); //but it this throws error
    //QueueInterface<int>* listPtr2 = new OurQueue<int>(); //but it this throws error


    cout << listPtr->isEmpty() << endl;
    return 0;
};

ArrayQueue implementation file:

/** ADT queue: Circular array-based implementation. @file ArrayQueue.cpp */

    #include "ArrayQueue.h"  // Header file

    template<class ItemType>
    ArrayQueue<ItemType>::ArrayQueue() : front(0), back(MAX_QUEUE - 1), count(0)
    {
    } // end default constructor

    template<class ItemType>
    bool ArrayQueue<ItemType>::isEmpty() const
    {
       return count == 0;
    } // end isEmpty

    template<class ItemType>
    bool ArrayQueue<ItemType>::enqueue(const ItemType& newEntry)
    {
       bool result = false;
       if (count < MAX_QUEUE)
       {
          // Queue has room for another item
          back = (back + 1) % MAX_QUEUE;
          items[back] = newEntry;
          count++;
          result = true;
       } // end if

       return result;
    } // end enqueue

    template<class ItemType>
    bool ArrayQueue<ItemType>::dequeue()
    {
       bool result = false;
       if (!isEmpty())
       {
          front = (front + 1) % MAX_QUEUE;
          count--;
          result = true;
       } // end if

       return result;
    } // end dequeue

    template<class ItemType>
    ItemType ArrayQueue<ItemType>::peekFront() const throw(PrecondViolatedExcep)
    {
       // Enforce precondition
       if (isEmpty())
          throw PrecondViolatedExcep("peekFront() called with empty queue");

       // Queue is not empty; return front
       return items[front];
    } // end peekFront
    // End of implementation file.

I get an error that is something like:

 ArrayQueue.cpp:7:1: error: redefinition of 'ArrayQueue<ItemType>::ArrayQueue()'
 ArrayQueue<ItemType>::ArrayQueue() : front(0), back(MAX_QUEUE - 1), count(0)
 ^~~~~~~~~~~~~~~~~~~~
In file included from ArrayQueue.h:31,
                 from ArrayQueue.cpp:3:
ArrayQueue.cpp:7:1: note: 'ArrayQueue<ItemType>::ArrayQueue()' previously declared here
 ArrayQueue<ItemType>::ArrayQueue() : front(0), back(MAX_QUEUE - 1), count(0)`enter code here`

One problem I see: you have to specify the template for the class you're extending

template <typename ItemType>
class OurQueue : public ArrayQueue<ItemType>

(and so forth)

First, I see a typo:

template<class ItemType>
class OurQueue : public ArrayQueue<ItemType> {
    OurQueue();                 // Default constructor
};

The constructor name was Ourqueue instead of OurQueue

Second:

These files should look something like this:

ArrayQueue.cpp

#include "ArrayQueue.h"

template<class ItemType>
ArrayQueue<ItemType>::ArrayQueue()
{
    //implementation
}

template<class ItemType>
bool ArrayQueue<ItemType>::isEmpty() const
{
    return true;
    //implementation
}

template<class ItemType>
bool ArrayQueue<ItemType>::enqueue(const ItemType& newEntry)
{
    return true;
    //implementation
}

template<class ItemType>
bool ArrayQueue<ItemType>::dequeue()
{
    return true;
    //implementation
}

main.cpp

#include <queue>
#include <iostream>
#include <string>

// Notice that I included the header and not the cpp
#include "ArrayQueue.h"

// Please don't use this. <.<
// using namespace std;

template<class ItemType>
class OurQueue : public ArrayQueue<ItemType> {
public:
    OurQueue()
    {

    }
};

int main() 
{
    QueueInterface<int>*listPtr = new OurQueue<int>(); //but it this throws error
    std::cout << listPtr->isEmpty() << std::endl;
    return 0;
};

I compiled them using clang:

clang++ main.cpp ArrayQueue.h

Compiled without any errors. You dont need to compile QueueInterface as it does not have any definitions. You can add it to compilation list though. It won't give any errors.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM