4

Here is the error I am receiving and need help resolving...

g++ -g -c -std=c++11 main.cpp
In file included from main.cpp:3:0:
Executive.h:18:25: error: cannot declare field 'Executive::queue' to be of abstract type 'ListQueue<std::basic_string<char> >'
  ListQueue<std::string> queue;
                         ^
In file included from Executive.h:12:0,
                 from main.cpp:3:
ListQueue.h:8:7: note:   because the following virtual functions are pure within 'ListQueue<std::basic_string<char> >':
 class ListQueue : public QueueInterface<ItemType>
   ^

I'm not used to using "virtual" classes or even C++ for that matter, still learning, but I'm having trouble compiling my code as it is now. The virtual classes were provided by the instructor, so I'm just going to post the header files for my Executive, ListQueue, and ArrayStack classes. ListQueue and ArrayStack are the classes related to their "virtual" QueueInterface and StackInterface classes.

Executive.h

    #include <iostream>
#include <string>
#include <fstream>

#include "ListQueue.h"
#include "ArrayStack.h"

class Executive
{
private:
    ListQueue<std::string> queue;
    ArrayStack<std::string> stack;
    std::string serving = "no one";
    std::string waiting = "no one";
    bool isWaiting = false;
    bool wasVIP = false;
    bool servingVIP = false;
public:

    /** Constructor reads in input file */
    Executive(std::istream& inputFile);

    /** Reads in and interprets the text file */
    void read(std::istream& is);

    /** Shows that the person currently being served finishes and the person waiting begins */  
    void done();

    /** Shows who is currently being served and who is next */
    void show();
};

ListQueue.h

 #include "QueueInterface.h"
#include "Node.h"

template<class ItemType>
class ListQueue : public QueueInterface<ItemType>
{
private:    
    Node<ItemType>* first; //front of queue
    Node<ItemType>* last; //end of queue

public:
    ListQueue();             // Default constructor
    bool isEmpty() const = 0;
    void enqueue(const ItemType& newEntry) throw (PrecondViolatedExcep) = 0;
    void dequeue() throw (PrecondViolatedExcep) = 0;
    ItemType peekFront() const throw (PrecondViolatedExcep) = 0;
}; // end ListQueue

ArrayStack.h

    #include "StackInterface.h"

const int MAX_STACK = 10;

template<class ItemType>
class ArrayStack : public StackInterface<ItemType>
{
private:    
    ItemType items[MAX_STACK]; // Array of stack items
    int      top;              // Index to top of stack

public:
    ArrayStack();             // Default constructor
    bool isEmpty() const;
    void push(const ItemType& newEntry) throw (PrecondViolatedExcep);
    void pop() throw (PrecondViolatedExcep);
    ItemType peek() const throw (PrecondViolatedExcep);
}; // end ArrayStack

StackInterface

template<typename ItemType>
class StackInterface
{
public:
   /** Sees whether this stack is empty.
    @return True if the stack is empty, or false if not. */
   virtual bool isEmpty() const = 0;

   /** Adds a new entry to the top of this stack.
    @pre a push is possible
    @post If the operation was successful, newEntry is at the top of the stack.
    @param newEntry The object to be added as a new entry. */
   virtual void push(const ItemType& newEntry)
        throw (PrecondViolatedExcep) = 0;

    /** Removes the top of this stack.
    @pre The stack is not empty.
    @post If the operation was successful, the top of the stack
    has been removed. */
   virtual void pop()
        throw (PrecondViolatedExcep) = 0;

   /** Returns the top of this stack.
    @pre The stack is not empty.
    @post The top of the stack has been returned, and
    the stack is unchanged.
    @return The top of the stack. */
   virtual ItemType peek() const throw (PrecondViolatedExcep) = 0;
}; // end StackInterface

QueueInterface

template<typename 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.
    @pre an enqueue is possible
    @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. */
   virtual void enqueue(const ItemType& newEntry)
        throw (PrecondViolatedExcep) = 0;

    /** Removes the front of this queue.
     @pre The queue is not empty.
     @post If the operation was successful, the front of the queue 
       has been removed. */
   virtual void dequeue()
        throw (PrecondViolatedExcep) = 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
        throw (PrecondViolatedExcep) = 0;
}; // end QueueInterface

cygwin winsymlinks:native doesn't work

I'm battling with cygwin for quite a while now.
I searched far and wide on how to make cygwin create Windows-style symbolic links.

I tried the following:

export CYGWIN="winsymlinks:native"
export CYGWIN="winsymlinks:nativestrict"
export CYGWIN="winsymlinks:lnk"
  • I also tried exporting w/o the quotes.
  • I also tried from both cygwin/x86 and cygwin/x64

For the life of me - I can't get the Windows native symlinks to work. I'm working on Windows7/64bit; cygwin version 1.7.25.

I'd love to get a solution for this one.

Thank you.

4

2 回答 2

3

您不能将队列声明为 List<std::string> 类型,您可以将其设为抽象类型 ListQueue<std::string> 的指针。与堆栈相同。

class Executive
{
        private:
    ListQueue<std::string> *queue;
    ArrayStack<std::string> *stack;
    std::string serving = "no one";
    std::string waiting = "no one";
    bool isWaiting = false;
    bool wasVIP = false;
    bool servingVIP = false;
public:
}

你不能这样做的原因是,如果它不是一个指针,编译器必须确定你的新类在内存中的形状,它需要知道你的类定义中字段类型的大小。然而,我不能为抽象类做到这一点,因为它不是一个完整的定义。如果你让它成为一个指向抽象类的指针,它可以计算出来,因为指针只是一个整数。


和你聊了一会儿,我意识到了错误。您正在继承老师给您的接口。当您编写代码以向其他人提供合同时,这是一个工具,该合同说为我构建一些可以做我想做的事情,这就是我将使用它的方式。

你的教授给你的接口定义是空的,没有定义函数应该做的逻辑。你的类应该继承他的接口,你已经完成了,但是你的类也应该填写所有方法的细节。

例如:

#include "QueueInterface.h"
#include "Node.h"

template<class ItemType>
class ListQueue : public QueueInterface<ItemType>
{
private:    
    Node<ItemType>* first; //front of queue
    Node<ItemType>* last; //end of queue

public:
    ListQueue();             // Default constructor
    bool isEmpty() const
    {
       // add logic here that will determine if the queue is empty.
    }

    void enqueue(const ItemType& newEntry) throw (PrecondViolatedExcep)
    {
       // Add logic to add element to queue
    }

    void dequeue() throw (PrecondViolatedExcep)
    {
       // add  logic to remove element from queue
    }

    ItemType peekFront() const throw (PrecondViolatedExcep)
    {
       // add logic to look at next element in queue without removing it.
    }

}; // end ListQueue

一旦您为这些接口填写了逻辑,您的类现在将被完全定义并且您可以使用它。您不限于那些可以添加辅助方法的方法以及构造函数、析构函数等。但您必须至少实现作为接口一部分的集合。

说得通?

那有意义吗。

于 2013-11-05T02:36:48.177 回答
0

Executive.h:18:25: error: cannot declare field 'Executive::queue' to be of abstract type 'ListQueue<std::basic_string<char> >' ListQueue<std::string> queue;

看起来这个类QueueInterface是一个抽象类。为了使用它,您已经ListQueue从它派生了类。

但是ListQueue该类具有以下内容:

bool isEmpty() const = 0;
void enqueue(const ItemType& newEntry) throw (PrecondViolatedExcep) = 0;
void dequeue() throw (PrecondViolatedExcep) = 0;
ItemType peekFront() const throw (PrecondViolatedExcep) = 0;  

这也使它变得抽象。

C++ 类中任何= 0以 结尾的方法都使其成为纯虚拟方法,而该类成为抽象类

现在抽象类不能被实例化。这是因为,它的行为是未知的(纯虚函数的定义不存在)

看下面的例子:

class Mammal
{
    public:
        virtual void breath() = 0;
}

现在类似的东西Mammal m会引发错误。为什么?要理解这一点,只需考虑以下代码:

// Assume the below line doesn't throw an error
Mammal m;

// m is now an object of type Mammal
m.breath();

你能从这条线上期待什么m.breath()?它没有定义,编译器完全不知道要执行什么。这就是它不起作用的原因。

那我该怎么办?Mammal从(抽象)类中派生出一个类

class Horse : public Mammal
{
    public:
        void breath();
}

void Horse::breath()
{
    // Code for horse breathing
}

所以在这里breath()定义了(即定义了哺乳动物的呼吸行为)我现在可以做类似的事情:

Horse h;
h.breath();

它会工作的!

如果您想知道拥有抽象类的意义,那是因为我可以拥有许多基类型的类Mammal,如下所示:

class Dog : public Mammal
{
    public:
        void breath()
        {
            // Dog's breathing code
        }
}

class Cat : public Mammal
{
    public:
        void breath()
        {
            // Cat's breathing code
        }
}

然后我可以做类似的事情:

// represents a generic mammal i.e it can be either a horse, a dog or a cat, that I can decide at run time
Mammal* m;

int i = 0;
cin >> i;
switch(i)
{
    case 0:
        m = new Horse();
    case 1:
        m = new Dog();
    case 2:
        m = new Cat();
    default:
        m = 0;
}

if(m!=0)
{
    m->breath();
    delete m;
}

这样你就可以在运行时调用适当的呼吸()

所以我想你已经知道你应该做什么:定义你的子类的方法定义(ListQueue在你的情况下)

于 2013-11-05T03:05:31.480 回答