Наследование с шаблонными классами и интерфейсами - PullRequest
0 голосов
/ 31 октября 2019

Цель: реализовать очередь. Проблема: Невозможно создать экземпляр класса "OurQueue" * примечание: класс "OurQueue" также должен иметь:

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

(но я даже не могу создать его экземпляр, поэтому я их не добавил)

Интерфейс:

/** @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

    /** 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 и основной файл

#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:

/** 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.

Я получаю сообщение об ошибке, похожее на:

 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`

Ответы [ 2 ]

0 голосов
/ 31 октября 2019

Во-первых, я вижу опечатку:

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

Имя конструктора было Ourqueue вместо OurQueue

Второе:

Эти файлы должны выглядеть примерно таквот так:

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;
};

Я скомпилировал их с помощью clang:

clang++ main.cpp ArrayQueue.h

Скомпилировано без ошибок! Вам не нужно компилировать QueueInterface, поскольку он не имеет каких-либо определений. Вы можете добавить его в список компиляции, хотя. Это не даст никаких ошибок.

0 голосов
/ 31 октября 2019

Я вижу одну проблему: вы должны указать шаблон для класса, который вы расширяете

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

(и т. Д.)

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