samedi 26 avril 2014

c ++ - ne peut pas déclarer un champ < nom_objet > comme étant de type abstrait - Stack Overflow


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

PROBLEM SOLVED!!!!!!!!


I just had to remove the zeros and I was able to keep from changing them to pointers! Thank you SOSOSOSOSOSOSO MUCH! ROB IS A CODING GOD




You cannot declare queue to be of type List<std::string> you can make it a pointer to abstract type ListQueue<std::string>. Same with the stack.


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

The reason you cannot do that is that if it is not a pointer, the compiler has to determine the shape in memory of your new class, it needs to know things like what size that the types of the fields in your class definition are. I however cannot do this for an abstract class, since it is not a complete definition. If you make it a pointer to an abstract class that it can figure out since pointers are just a integer.




After talking with you a bit I realize the mistake. You are inheriting interfaces your teacher gave you. This is a tool when you write code to give other people a contract that says build me something that will do what I want and this this the way I will use it.


The interface definition your professor gave you are empty, there is no logic that defines that the functions should do. Your classes are supposed to inherit his interfaces, which you have done, but you classes are also supposed to fill in the details for all the methods.


For example:


#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

Once you have filled out the logic for those interfaces your class will now be fully defined and you can use it. You are not restricted to those methods you can add helper methods if you like and constructors, destructors etc.. but you MUST implement at least the set that is part of the interface.


Makes sense?


Does that make sense.




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


It seems like the class QueueInterface is an abstract class. In order to use it you have derived the ListQueue class out of it.


But the ListQueue class has the following:


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

Which makes it abstract as well.


Any method in a C++ class with an = 0 at the end makes it a pure virtual method and the class an abstract class.


Now abstract classes cant be instantiated. This is because, the it's behavior is not known (the definition of the pure virtual function doesn't exist)


Look at the following example:


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

Now something like Mammal m throws an error. Why? To understand this, just consider the following code:


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

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

What can you expect from the line m.breath() ? It doesn't have a definition and the compiler gets absolutely no idea as to what is to be executed. That's the reason it doesn't work.


What do I do then? Derive a class out of the Mammal (abstract) class


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

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

So here the breath() is defined (i.e. the mammal's breathing behavior is defined) I can now do something like:


Horse h;
h.breath();

and it'll work!


If you want to know the point of having an abstract class, it's because I can have many classes of base type Mammal as follows:


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

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

and then I can do something like:


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

So that way you can call the appropriate breath() at run-time


So I guess you've got an idea as to what you're supposed to do: Define your the method definition of your sub-classes (ListQueue in your case)



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

PROBLEM SOLVED!!!!!!!!


I just had to remove the zeros and I was able to keep from changing them to pointers! Thank you SOSOSOSOSOSOSO MUCH! ROB IS A CODING GOD



You cannot declare queue to be of type List<std::string> you can make it a pointer to abstract type ListQueue<std::string>. Same with the stack.


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

The reason you cannot do that is that if it is not a pointer, the compiler has to determine the shape in memory of your new class, it needs to know things like what size that the types of the fields in your class definition are. I however cannot do this for an abstract class, since it is not a complete definition. If you make it a pointer to an abstract class that it can figure out since pointers are just a integer.




After talking with you a bit I realize the mistake. You are inheriting interfaces your teacher gave you. This is a tool when you write code to give other people a contract that says build me something that will do what I want and this this the way I will use it.


The interface definition your professor gave you are empty, there is no logic that defines that the functions should do. Your classes are supposed to inherit his interfaces, which you have done, but you classes are also supposed to fill in the details for all the methods.


For example:


#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

Once you have filled out the logic for those interfaces your class will now be fully defined and you can use it. You are not restricted to those methods you can add helper methods if you like and constructors, destructors etc.. but you MUST implement at least the set that is part of the interface.


Makes sense?


Does that make sense.



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


It seems like the class QueueInterface is an abstract class. In order to use it you have derived the ListQueue class out of it.


But the ListQueue class has the following:


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

Which makes it abstract as well.


Any method in a C++ class with an = 0 at the end makes it a pure virtual method and the class an abstract class.


Now abstract classes cant be instantiated. This is because, the it's behavior is not known (the definition of the pure virtual function doesn't exist)


Look at the following example:


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

Now something like Mammal m throws an error. Why? To understand this, just consider the following code:


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

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

What can you expect from the line m.breath() ? It doesn't have a definition and the compiler gets absolutely no idea as to what is to be executed. That's the reason it doesn't work.


What do I do then? Derive a class out of the Mammal (abstract) class


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

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

So here the breath() is defined (i.e. the mammal's breathing behavior is defined) I can now do something like:


Horse h;
h.breath();

and it'll work!


If you want to know the point of having an abstract class, it's because I can have many classes of base type Mammal as follows:


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

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

and then I can do something like:


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

So that way you can call the appropriate breath() at run-time


So I guess you've got an idea as to what you're supposed to do: Define your the method definition of your sub-classes (ListQueue in your case)


0 commentaires:

Enregistrer un commentaire