Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
Solved

# C++ Inheritance Polymorphism

Posted on 2008-06-19
Medium Priority
458 Views
I asked a similar question before (see http://www.experts-exchange.com/Programming/Languages/CPP/Q_23478995.html) but i have to refine my question.

I do abstract.h , which is an abstract class of an queueElement. From those, i can inheritance/derive other classes like queueElementInt, queueElementFloat and so on.

I do also have a class Queue, in which I have to insert objects from the class queueElement as elements of my queue. On the queue i can perform certain operations like queue or dequeue, as seen in the code snippet

I did work with inheritance before (class QueueClass: public QueueElement) but it is a pretty silly inheritance, since QueueClass has nothing to do with QueueElement.

I also understand the using of ploymorphism, but it does not get into my mind if my solution, which i post in the codesnippets work. I appreciate all the great answers from all the fine people arround here.

Since this is a new angle of my question, i opened a new one to reward the good work of the people arround here. Please help me out of my misery
``````class QueueElement {
public:
virtual ~QueueElement(){}
double data;
QueueElement *next;

void setData(double d)
{
data=d;
}

double getData()
{
return data;
}

QueueElement const *getNext() const
{
return next;
}
};
/// no further inhertince to QueueElementint and so on done.

#include <iostream>

using namespace std;

#define SIZE 20
#include "abstract.h"
class QueueClass{
private:
int queue[SIZE];
int num;

public:
QueueClass();
void qu(QueueElement* newElement);
int dequ();
int size();
int isEmpty();
};

QueueClass::QueueClass()
{
}

void QueueClass::qu(QueueElement* newElement)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE) tail = 0;
queue[tail] = num;
}

int QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

int QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;

}
``````
0
Question by:george08
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 83
• 63

LVL 53

Accepted Solution

Infinity08 earned 2000 total points
ID: 21822216
Your queue seems to be made to store ints rather than QueueElements ... Are you aware of that ?

I assume that this is an assignment ? If so, can you show us the exact assignment you got ?
If not, why not simply use the STL queue ?

http://www.cplusplus.com/reference/stl/queue/

Did you learn about templates yet ? If so, may I offer a suggestion : why not create a templated queue class ?
0

Author Comment

ID: 21823152
To be exact, thats how it should work

I have to write an abstract Class QueueElement, which is the parent class for the objects, which i can put in my queue.

I already wrote a template, but it should be not a template this time, it should be done with inclusion polymorphism.
0

Author Comment

ID: 21823176
0

LVL 53

Assisted Solution

Infinity08 earned 2000 total points
ID: 21823201
>> I have to write an abstract Class QueueElement,

An abstract base class (ABC) has to have at least one pure virtual member.

Take a look at these FAQ entries - they will surely be very helpful :)

http://www.parashift.com/c++-faq-lite/abcs.html
0

LVL 53

Expert Comment

ID: 21823217
>> And my Queue only stores Objects of QueueElement...??

Where ? You have an array of int to store the elements in the queue :

>>   int queue[SIZE];

Also, notice that your qu method doesn't make use of its parameter - it doesn't actually insert the element into the queue ...
0

LVL 53

Expert Comment

ID: 21823233
The rest of the Queue class is also made for ints - did you copy this code from somewhere ? Do you understand it ?
0

Author Comment

ID: 21823430
Okey, here is my template queue i made myself with the help of other fine users arround here....

I think that this is a good point to start, is not it?

Within my template i do have my methode i.e.

void QueueClass<T>::qu(T num)             //init declarator before < token //expected ; befor < token
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE) tail = 0;
queue[tail] = num;
}

where i can replace T num by a pointer of the type QueueElement (Queueelement* newElement)

I do understand that i wrote a wrong virtual class, which i'm taking care of pretty soon.

``````///queuet.h

#ifndef QUEUET_H
#define QUEUET_H

#include <iostream>
using namespace std;

#define SIZE 20

template <typename T>
class QueueClass
{

T queue[SIZE];
public:

QueueClass(T, T);
~QueueClass(){};

void qu(T num);

T dequ();
T size();
T isEmpty();
};

#endif

////qeuet.cc
#include "QUEUET.H"

template <typename T>
QueueClass<T>::QueueClass (T a, T b) { 		//expected ; befor < token
tail = b;

}

template <typename T>

void QueueClass<T>::qu(T num) 		//init declarator before < token //expected ; befor < token
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE) tail = 0;
queue[tail] = num;
}

template <typename T>

T QueueClass<T>::dequ()		//init declarator before < token //expected ; befor < token
{
cout << "Queue is empty\n";
return 0;
}
}

template <typename T>
T QueueClass<T>::size()
{ 							//init declarator before < token //expected ; befor < token
T j=0;
for (; j<tail; j++){
}
return j;
}

template <typename T>

T QueueClass<T>::isEmpty()
{  				//init declarator before < token //expected ; befor < token
cout << "Queue is empty\n";
return 1;
}
else return 0;
}

/// main.cc

#include <iostream>
#include "queuet.cc"
using namespace std ;
int main()
{
QueueClass<int> queue1 (1,1);  ////expected ; before int //QueueClass undeclared  //expect primary expression before int

cout<<"If 1, Queue is Empty, else 0 aka Queue is not empty. Result: " <<queue1.isEmpty()<<endl;
int i;
for(i=1; i <=10; i++) {
queue1.qu(i);        // queue1 undecleared, first use
}
cout<<"If 1, Queue is Empty, else 0 aka Queue is not empty. Result: " <<queue1.isEmpty()<<endl;
cout<< queue1.size() <<" test" <<endl;

for(i=1; i <=10; i++)
cout << "Dequeue 1: " << queue1.dequ() << endl;

return 0;
}
``````
0

Author Comment

ID: 21823689
Here is my (hopefully) abstract class

``````#include <iostream>
using namespace std;

class QueueElement {
private:
QueueElement *next;
double data;
QueueElement(int d){
data=d;
next=0L;
}
virtual ~QueueElement(){
}

virtual setData( d) =0;

virtual QueueElement::getData() =0;

virtual QueueElement::*getNext() =0;

};
``````
0

Author Comment

ID: 21823836
Here we do have the abstract class and two other classes which derive from that

Is that correct?

We have got virtual functions, the destructor is virtual and in the derived classes, all functions where proper written. (Hopefully)

Thanks!

``````#include <iostream>
using namespace std;

class QueueElement {
private:
QueueElement *next;
double data;
QueueElement(int d){
data=d;
next=0L;
}
virtual ~QueueElement(){
}

virtual setData( d) =0;

virtual getData() =0;

virtual *getNext() =0;

};

class QueueElementInt : public QueueElement
{
public:
QueueElementInt();
~QueueElementInt();

void setData(d){
data=d;
}

int getData(){
return data;
}

QueueElementInt *getNext(){
return next;
}
};

class QueueElementFloat : public QueueElement
{
public:
QueueElementInt();
~QueueElementInt();

void setData(d){
data=d;
}

float getData(){
return data;
}

QueueElementInt *getNext(){
return next;
}
};
``````
0

LVL 53

Expert Comment

ID: 21824566
>> Okey, here is my template queue

I thought you said you shouldn't use templates ? Which is it ?

>> Here we do have the abstract class and two other classes which derive from that

It's abstract, but a few remarks :

1) What is the next member supposed to do ? You're not making a linked list are you ?

2) your setters and getters are missing a return type ...

3) your methods are all private ...

4) why did you choose a double data member for the ABC ? That doesn't make sense, does it ? The choice of data member should be left to the derived classes, no ?
0

Author Comment

ID: 21824672
I'm sure i can use my template class to change it so that i can use it as a raw modell for my new objective.

As I stated above, i need to put in objects of my QueueElement class in my Queue Class. And with a template, it should be easier to start on.

And please do me a favour, I'm not that experieciend in CPP, so do not give me a hard time. ;-) Finishing this work properly helps me really out of a serious situation....

To my abstract class:

I'm not totally sure about what is with my next member - a friend told me so. I changed it all back.
With that private and public: stupid mistake by me, sorry.

``````#include <iostream>
using namespace std;

class QueueElement {
private:
double data;
public:

QueueElement(int d){
data=d;
next=0L;
}
virtual ~QueueElement(){
}

virtual voidsetData( d) =0;

virtual int getData() =0;

//  virtual *getNext() =0;

};

class QueueElementInt : public QueueElement
{
public:
QueueElementInt();
~QueueElementInt();

void setData(d){
data=d;
}

int getData(){
return data;
}

};

class QueueElementFloat : public QueueElement
{
public:
QueueElementInt();
~QueueElementInt();

void setData(d){
data=d;
}

float getData(){
return data;
}

};
``````
0

LVL 53

Assisted Solution

Infinity08 earned 2000 total points
ID: 21824752
The whole point of having an ABC in this case is to have a common interface for all elements that could be added to the queue.

The ABC defines that interface. It has no implementation or data members. It just defines which member methods need to be implemented by the derived classes.

The derived classes then will be the ACTUAL elements. They contain the necessary data member(s) and implement the methods defined in the ABC.

If you do that properly, then you can create a queue of pointers to the ABC. The queue will only call the methods defined in the ABC (ie. the interface methods).
When adding a specific element to the queue, you create an instance of that specific element (IntQueueElement or whatever), and store a pointer to it in the queue.

Do you understand how virtual methods work ?
0

Author Comment

ID: 21824839
I do understand the concept of ABC and interfaces as well as of virtual methods. But I'm NOT seeing the way of eleminating my int and double values in my ABC. I also do understand virtual methods, they are methods without a body, so that they can be written later in the derived class.

I also do understand the concept the concept of storing a pointer in the queue, this should be nothing else more than storing an int value to my queue. But I do not totally get it, I do know pointers but I'm not totally sure who to handle them properly. That is why I'm here, writing. I'm also willing to learn, but i did spent hours over hours over that and cannot make a step forward.
0

LVL 53

Assisted Solution

Infinity08 earned 2000 total points
ID: 21825311
>> I do understand the concept of ABC and interfaces as well as of virtual methods.

I'm sorry to say, but I don't think you do :) Not completely anyway.

>> But I'm NOT seeing the way of eleminating my int and double values in my ABC.

Just don't put them in there ... put them in the derived classes. The ABC will NEVER be instantiated. It is simply an interface, nothing more. There's no data in it, nor is there any implementation in it.

>> I also do understand virtual methods, they are methods without a body, so that they can be written later in the derived class.

That's not quite correct. I suggest you do some reading about them first. Here's a good start :

http://www.parashift.com/c++-faq-lite/virtual-functions.html

>> this should be nothing else more than storing an int value to my queue.

I'm not sure what you mean by that, but ints and pointers are quite different.

>> That is why I'm here, writing. I'm also willing to learn,

I understand that, and I'm trying to teach ;)

>> but i did spent hours over hours over that and cannot make a step forward.

You have to understand all the concepts involved first before starting to write code. If not, you end up wasting a lot of time as you noticed :)
0

Author Comment

ID: 21825475
>>I'm sorry to say, but I don't think you do :) Not completely anyway.

Hey, I never said I'm perfect

>>Just don't put them in there ... put them in the derived classes. The ABC will NEVER be instantiated. It is simply an interface, nothing >>more. There's no data in it, nor is there any implementation in it.

That is a problem for me. You said above that i did not put a return type on me getter and setters... But which return type should i take? a virtual? All my google results does not give me a solution, they only say arbitrary....

>>That's not quite correct. I suggest you do some reading about them first. Here's a good start :

http://www.parashift.com/c++-faq-lite/virtual-functions.html

>>I'm not sure what you mean by that, but ints and pointers are quite different.

I do know that there is a difference, but for my queue, it should not matter if there are int parts in my queue or pointers...

>>I understand that, and I'm trying to teach ;)

I really appreciate your offer, I'm totally willing to listen.

Thanks

>> but i did spent hours over hours over that and cannot make a step forward.

You have to understand all the concepts involved first before starting to write code. If not, you end up wasting a lot of time as you noticed :)
0

LVL 53

Expert Comment

ID: 21825598
>> Hey, I never said I'm perfect

It wasn't meant negatively. Just that the first step of learning something is to acknowledge that you need to learn it :)

>> You said above that i did not put a return type on me getter and setters... But which return type should i take? a virtual?

If the different derived classes will return different types, then that's not possible. In that case, you have to ask yourself if using an ABC is the right choice.

Virtual methods are good if you plan to store data of different types in the same queue.
Templated queues are good at handling queues of different element types without having to write the same code over and over.

Can you show me the exact assignment you got ? Because it seems there are some conflicting requirements there :)
0

Author Comment

ID: 21825689
The Assignement is not in English, that's the point. I'm not a native speaker also, as u might have seen ;-)

I was done to do an abstract class from which QueueElementWhatever1 and QueueElementWhateverII derive.
To surpass the system of having different return types, can't we eleminate the power of the virtual methods and put all the nesserary methods in the derived classes? That's not elegant, but it works.

Then i was asked to transform my template in that way, that i can put Queueelements to my queue.

That's another problem too. I know that i have to use polymorhism, but to my limited knowledge, i can only use polymorphis together with inheritance.

But i do not wanna use class QueueClass: public QueueElement

The Assignement is doable, that's for sure. And i got that advise about having to derived classes (whateverI and whateverII) and not using class QueueClass: public QueueElement

It should be done with polymorphism.

I hope you do understand my miserary and can help me out. Thanks.
0

LVL 53

Assisted Solution

Infinity08 earned 2000 total points
ID: 21825820
>> That's not elegant, but it works.

What's the point of having an abstract base class then ?

>> Then i was asked to transform my template in that way, that i can put Queueelements to my queue.

If you have a properly implemented templated queue, then you don't have to modify it. It will just work with whatever type you choose.

>> but to my limited knowledge, i can only use polymorphis together with inheritance.

That's kind of the point ... how will you make use of polymorphism otherwise ? Did you read the FAQs I posted earlier ? Did you understand them ? Do you have any questions about them ?

Here's another take on it - maybe this will make things clearer :

http://www.cplusplus.com/doc/tutorial/polymorphism.html

Take your time reading through it (and also take a look at the other chapters of that tutorial), and ask questions whenever something is unclear.

>> But i do not wanna use class QueueClass: public QueueElement

Why would you do that ?

>> I hope you do understand my miserary and can help me out. Thanks.

I don't really understand what your assignment asks you to do. Can you post a literal translation of the assignment ?
0

Author Comment

ID: 21825867
Thats it

Class queue element, as the base class for the objects that would
in the queue will be.

See below my template, which works....

THANK YOU
``````#include "QUEUET.H"

template <typename T>
QueueClass<T>::QueueClass (T a, T b) {
tail = b;

}

template <typename T>

void QueueClass<T>::qu(T num)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE) tail = 0;
queue[tail] = num;
}

template <typename T>

T QueueClass<T>::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

template <typename T>
T QueueClass<T>::size()
{
T j=0;
for (; j<tail; j++){
}
return j;
}

template <typename T>

T QueueClass<T>::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;
}
``````
0

LVL 53

Expert Comment

ID: 21826088
>> now inheritance (Inclusionspolymorphism).

Inheritance is not the same as polymorphism. Please take a look at the tutorial and FAQ articles I posted earlier. I really suggest reading up on all these concepts before continuing. You seem to be rushing into this.

As I tried to explain earlier : you cannot just replace templates with polymorphism .. they're two completely different concepts used for different purposes.
0

Author Comment

ID: 21826111
google translate did a poor job on this

instead of template do inheritance, that's what i really is....
0

Author Comment

ID: 21826153
"instead templates do now inheritance "

thats the correct meaning. google translate was not perfect.

My problem with all tutorials you post... there is always an inheritance involved...

My problem is, that i cannot use inheritance von queueelement to queue...

that is what i do not get....
0

Author Comment

ID: 21826396
Here we go again...

I do have again my abstract class and two classes which derive from them. Because I do have two different classes derived from my base, i did chose double as data type.

Next step i do, is to write a queue.h (from my understanding i can also use my template?)

The third step would be writing a main.cc in which i include my queueelement headerfiles AND my queue.h file.

From thereon use constructors to construct objects of my queueelment and an object of my queue?

is that hopefully a correct thought? is that what ploymorphis is about?
``````#include <iostream>
using namespace std;

class QueueElement {
private:
double data;
public:

QueueElement(int d){
data=d;

}
virtual ~QueueElement(){
}

virtual void set Data( d) =0;

virtual double getData() =0;

};

class QueueElementFloat : public QueueElement
{
public:
QueueElementInt();
~QueueElementInt();

void setData(d){
data=d;
}

double getData(){
return data;
}

};

class QueueElementDouble : public QueueElement
{
public:
QueueElementInt();
~QueueElementInt();

void setData(d){
data=d;
}

double getData(){
return data;
}

};
``````
0

Author Comment

ID: 21826929
Forget what i said above...

I do have a base class and two derived classes.

So in my main, i construct one objects from my base class like this

QueueElementdouble *newElement;

which i can use in my queue.

To suceed, i do have to include my baseclass as well as my derived classes in my main file?

That should be polymorphism too?

0

LVL 53

Expert Comment

ID: 21826978
>> My problem is, that i cannot use inheritance von queueelement to queue...

Who says you need to inherit Queue from QueueElement ? You have different types of QueueElements, don't you ? And all of them have one thing in common ... what ?

>> "instead templates do now inheritance "
>> (from my understanding i can also use my template?)
>> is that what ploymorphis is about?

??????? These three do not make a lot of sense together in the same post ...

Stop, rewind ... ;)

Did you find the time to read the tutorial I posted ? Did you understand all of it ?

I have to be honest, I still don't quite understand what the assignment is about - it just doesn't make sense to replace templates with inheritance (let alone polymorphism).

What was the original language the assignment was in ? Can you post that, and also the first assignment (the one for which you made the templated code) ?
0

Author Comment

ID: 21827017
>>Who says you need to inherit Queue from QueueElement ? You have different types of QueueElements, don't you ? And all of them have one thing in common ... what ?

Sorry, I'm too tired for guessing....

Who said that assignement should make sense? ;-)
I just know that this assignement is doable and it can't be too problematic, but i cannot see the trick i have to perform on this.
The assignment ist german.

Tutorials
Yes, i do think that i do understood most of it, and i do know that i can use

QueueElementdouble *newElement;

to make a pointer to my base class. by doing so, i can use the pointer as a part of my queue.

0

LVL 53

Expert Comment

ID: 21827040
>> I'm too tired for guessing....

I'm not asking you to guess ;) I'm asking you to try to understand this :) That's what this is about, isn't it.

If you're feeling tired, then maybe it's time to take a break, and start again later with a fresh head. And as I said a few times earlier already : understanding the concepts before writing any code is very important. You will only confuse yourself otherwise (as you've apparently been doing until now), and that works counterproductively.

>> The assignment ist german.

So ? can you post both of them ?
0

Author Comment

ID: 21827082
The Assignment
1. Schreiben Sie eine Klasse Queue (FIFO) ohne Verwendung von Template mit einem statischen Array
2. Formen Sie die Klasse in ein Template um
3. Wandeln Sie die Klasse Queue so um, dass statt einem Template nun Vererbung (Inklusionspolymorphismus) verwendet wird
Wandeln Sie Ihre Klasse Queue so um, daÃŸ statt Templates nun Vererbung.
Schreiben Sie dazu eine abstrakte Klasse QueueElement, die als Basisklasse fuer Objekte dient, die in der Queue abgelegt werden.

Both different QueueElements have their BaseClass in common. They also have in common that they are both capable of being part of the queue.

0

LVL 53

Expert Comment

ID: 21827144
I don't see anywhere in this assignment that the queue elements need to contain data. So, for the third part, I would not put any data in at all. Just create a method that prints something to the screen or something similar. That should be more than sufficient to showcase polymorphism.

>> They also have in common that they are both capable of being part of the queue.

Exactly :) So, it's not the Queue class that inherits ...

I need to get some sleep now :)
0

Author Comment

ID: 21827149
thanks for your time and patience... good night
0

Author Comment

ID: 21829062
Here we go :-)

My abstract class an two classes which derive from these...
``````#include <iostream>
using namespace std;

class QueueElement {
private:

public:

QueueElement(){

}
virtual ~QueueElement(){
}

virtual void print() =0;

};

class QueueElementFloat : public QueueElement
{
public:
QueueElementInt();
~QueueElementInt();

void print(){
std::cout<<"I'm QueueElementFloat" <<std::endl;
}

};

class QueueElementIny : public QueueElement
{
public:
QueueElementInt();
~QueueElementInt();

void print(){
std::cout<<"I'm QueueElementInt" <<std::endl;
}

};
``````
0

LVL 53

Expert Comment

ID: 21829104
>> My abstract class an two classes which derive from these...

That looks good. You can do something with that. Now, modify the Queue class to hold these elements.
0

Author Comment

ID: 21829154
Here we go:
``````#include <iostream>

using namespace std;

#define SIZE 20
#include "abstract.h" //That should be my Base class
class QueueClass{
private:
int queue[SIZE];
int num;

public:
QueueClass();
void qu(QueueElement* newElement);
int dequ();
int size();
int isEmpty();
};

QueueClass::QueueClass()
{
}

void QueueClass::qu(QueueElement* newElement)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE) tail = 0;
queue[tail] = num;
}

int QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

int QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;

}
``````
0

LVL 53

Expert Comment

ID: 21829167
That's the same as what you posted earlier. My comments are still valid. This is a queue that stores ints ... You have to make it store your queue elements.
0

Author Comment

ID: 21829180
Yeah I saw. Is there a possibitly of editing posts?

But now, my QueueClass should only hold QueueElements, not ints
``````#include "QUEUET.H"

QueueClass::QueueClass (QueueElement* a, QueueElement* b) {
tail = b;

}

void QueueClass::qu(QueueElement* num)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE) tail = 0;
queue[tail] = num;
}

QueueElement QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

boolean QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return true;
}
else return false;
}
``````
0

LVL 53

Expert Comment

ID: 21829229
>> Is there a possibitly of editing posts?

No ;)

1) Why does your constructor take two pointers ? Shouldn't a queue have a default (empty) initialization ?

2) Wouldn't it be nice to have an isFull method ? And make sure to call it wherever appropriate (also the isEmpty method) ... you don't want to duplicate code ;)

3) Take a look at the return type for dequ.

4) What's the size method doing ? Do you need that loop ? Is it returning the correct result ?
0

Author Comment

ID: 21829295
I should start systematicly, I really tend to rush of to these things sometimes without thinking.

This is my Queue.h
``````#ifndef QUEUE_H
#define QUEUE_H

#include <iostream>
using namespace std;

#define SIZE 20

class QueueClass
{

QueueElement queue[SIZE];
public:

QueueClass();
~QueueClass(){};

void qu(QueueElement* num);

void dequ();
int size();
boolean isEmpty();
};

#endif
``````
0

LVL 53

Expert Comment

ID: 21829382
>> I should start systematicly

That's a very good idea ;)

>> #include <iostream>
>> using namespace std;

You are not making use of iostream in the header, so you shouldn't include it in the header.
Also, putting using namespace std; in a header file is almost always a bad idea, since you're dumping the whole std namespace into every file that (indirectly) includes the header file.

>>   QueueElement queue[SIZE];

In order to make use of the polymorphism, you'll have to store pointers rather than the elements themselves.

head and tail have to be pointers too, for obvious reasons. If you don't understand why, please ask.

>>   void dequ();

Don't you want to return something ?

>>   boolean isEmpty();

What's boolean ?
Don't you want an isFull too ?
0

Author Comment

ID: 21829407
>>That's a very good idea ;)
again, thanks for guiding me. i think this will be a very productiv day.

>>You are not making use of iostream in the header, so you shouldn't include it in the header.
>>Also, putting using namespace std; in a header file is almost always a bad idea, since you're dumping the whole std namespace into >>every file that (indirectly) includes the header file.

Someone told me that sometime, but i forgot.

>>In order to make use of the polymorphism, you'll have to store pointers rather than the elements themselves.

>>   void dequ();

Why should I?

>>>>   boolean isEmpty();
>> What's boolean ?

Boolean should be a return typ. As i might remember, it could be done in java, which i learned better than cpp

>>Don't you want an isFull too ?
No intend in doing so... these methods i have should do just fine.
0

Author Comment

ID: 21829454
boolean is bool

0

Author Comment

ID: 21829586
How can i include my QueueElement to my Queue.h?
``````#ifndef QUEUE_H
#define QUEUE_H

#define SIZE 20

class QueueClass
{

QueueElement* queue[SIZE];
public:

QueueClass();
~QueueClass(){};

void qu(QueueElement* num);

void dequ();
int size();
bool isEmpty();
};

#endif
``````
0

Author Comment

ID: 21829712
This is my class Queue which should work.

But I do have still the question. How do I include my QueueElement?

``````#include <iostream>

#define SIZE 20
#include "abstract.h"
class QueueClass
{

QueueElement* queue[SIZE];
public:

QueueClass();
~QueueClass(){};

void qu(QueueElement* newElement);

QueueElement* dequ();
int size();
bool isEmpty();
};

QueueClass::QueueClass()
{

}

void QueueClass::qu(QueueElement* newElement)
{
std::cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE) tail = 0;
queue[tail] = newElement;
}

QueueElement* QueueClass::dequ()
{
std::cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

bool QueueClass::isEmpty()
{
std::cout << "Queue is empty\n";
return 1;
}
else return 0;

}
``````
0

LVL 53

Expert Comment

ID: 21829776
>> >>   void dequ();
>>
>> Why should I?

The point of de-queue-ing is to get the next element from the queue. If you don't return anything, then ... ;)

>> boolean is bool

Correct. There is no boolean type in C++ (unless you define it yourself). bool should be used instead.

>> >>Don't you want an isFull too ?
>> No intend in doing so... these methods i have should do just fine.

It will make the code a lot clearer, and your life a lot easier. I would add it :)

>> How can i include my QueueElement to my Queue.h?

Just include the header file that contains the class definitions for the QueueElement class.

>> This is my class Queue which should work.

Do you mean that that code you posted is the .cpp file ? Why did you re-write the QueueClass class ? You should have simply included the queueclass.h header file.

I said this earlier :

>>
>> head and tail have to be pointers too, for obvious reasons. If you don't understand why, please ask.

But I just noticed that you are using head and tail as array indexes ... So, they need to be ints ... and properly initialized in the queue's constructor.

Also, take a look at this remark I made earlier :

>> 4) What's the size method doing ? Do you need that loop ? Is it returning the correct result ?

What is the size of the queue ? How can you easily calculate it ?
0

Author Comment

ID: 21829821
>>Do you mean that that code you posted is the .cpp file ? Why did you re-write the QueueClass class ? You should have simply included >>the queueclass.h header file.

Okay, I did make a step too much. Please show me where to start. I cannot see it in that moment. Also in regard to head and tail as int.

>> 4) What's the size method doing ? Do you need that loop ? Is it returning the correct result ?

To my knowledge, Size() just gives me back how many elements are in my array. I do run through my array until i find tail, then i know how many elements are in my queue.

>> >>   void dequ();
>>
>> Why should I?
>
>The point of de-queue-ing is to get the next element from the queue. If you don't return anything, then ... ;)

So I do have QueueElement* dequ(){}

> >>Don't you want an isFull too ?
>> No intend in doing so... these methods i have should do just fine.
>>
>>It will make the code a lot clearer, and your life a lot easier. I would add it :)

Where to begin?

bool isFull()
{

}

0

LVL 53

Expert Comment

ID: 21829994
>> Okay, I did make a step too much. Please show me where to start.

What do you mean ? Can you show me all of the files you currently have ?

>> Also in regard to head and tail as int.

How are you using head and tail ? What type do they need to have in order to be able to use them that way ?

>> To my knowledge, Size() just gives me back how many elements are in my array.

Correct.

>> I do run through my array until i find tail, then i know how many elements are in my queue.

Let me repeat the other questions I asked :

>> Do you need that loop ? Is it returning the correct result ?

>> Where to begin?
>>
>> bool isFull()
>>  {
>>
>>  }

That's it - now just implement it ;)
0

Author Comment

ID: 21830046
>>The Assignment
>>1. Schreiben Sie eine Klasse Queue (FIFO) ohne Verwendung von Template mit einem statischen Array
>>2. Formen Sie die Klasse in ein Template um
>>3. Wandeln Sie die Klasse Queue so um, dass statt einem Template nun Vererbung (Inklusionspolymorphismus) verwendet wird
>>Wandeln Sie Ihre Klasse Queue so um, daÃŸ statt Templates nun Vererbung.
>>Schreiben Sie dazu eine abstrakte Klasse QueueElement, die als Basisklasse fuer Objekte dient, die in der Queue abgelegt werden.

The attached file incl. part 1, part 2 and part 3 which are different parts of my assignment.
0

Author Comment

ID: 21830070
>>int QueueClass::size()
>>{
>>    int j=0;
>>  for (; j<tail; j++){
>>  }
>>  return j;
>>  }

The loop runs from 0 up to the tail-1. I Think that is the mistake, because Size() gives me size-1

Correct?
0

LVL 53

Expert Comment

ID: 21830239
>> The attached file incl. part 1, part 2 and part 3 which are different parts of my assignment.

I asked for the code, not the assignment ;)

>> The loop runs from 0 up to the tail-1. I Think that is the mistake, because Size() gives me size-1
>>
>> Correct?

I'll ask the question once more : do you need that loop ?

Think about what head and tail are, and how the size of the queue is defined. Then think about how you can get that size ...
0

Author Comment

ID: 21830337
I just connect the code i wrote to my assignment, so that it can be easier to track down whats what....

Ok, to my loop problem. Since my loop does work, can't we concentrate on matters which are more important for me, please?
I gotta finish this thing up....
0

LVL 53

Expert Comment

ID: 21830475
>> Since my loop does work

Actually it doesn't :)

>> can't we concentrate on matters which are more important for me, please?

You can concentrate on any of the issues I pointed out ... it's your choice. But in the end, you will have to fix all of them.

If you're unsure about what to do next, I suggest reading back a bit for all the issues I already pointed out.
0

Author Comment

ID: 21830517
My problem is, that I

a. do not see the error in the loop
b. don't see the point why i need isFull() Method, since I was told that empty() q() deq() and size() would be enough
c. you totally confused me whether to use head or tail with int....

So I asking to give me a hand and guide me. But with all that I have right now, i do not the the light i can walk towards....
0

LVL 53

Expert Comment

ID: 21830578
>> a. do not see the error in the loop

I assumed you could read between the lines when I asked "do you need that loop ?". The answer is of course : no. There is no reason for the loop, since all it does is just count to a predefined value. You might as well just have returned that value. There's no need to waste processor cycles with a loop.

But then there's still the problem that the value returned is incorrect. The size of the queue is the distance between the head and the tail of the queue ... Let that sink in a bit, and then think about how you can calculate that.

>> b. don't see the point why i need isFull() Method, since I was told that empty() q() deq() and size() would be enough

The point is that you are already using code that determines whether the queue is full. If you put that in an isFull method, and call that method whenever you need to know whether the queue is full, your code will be a lot easier to read and maintain.

Similarly, you have an isEmpty function, but you don't use it. Instead, you duplicated the code to determine if the queue is empty, while you could have simply called the isEmpty method.

>> c. you totally confused me whether to use head or tail with int....

As I said : think about what head and tail are. Look at how you are using head and tail. Then determine which data type they need to be.
Take it one step at a time. You're only confusing yourself by trying to be too fast :)
0

Author Comment

ID: 21830637
first of all thanks.
But i do not care about optimizing the code, I'm trying to solve my problem and i do not care at the moment whether the code is inefficient. i just wanna write stable code, which just runs. optimizing comes later. So my concers are focused on getting this thing up running....

The problem in the difference between head and tail is that it is one too short for giving the real size, so it should be: (tail-head)+1

My head and my tails are parts of the queue, if its an int queue, its int, if its double queue its double if its QueueElement* Queue its QueueElement*
....

This whole thing is bugging me since more than 2 weeks now, and my final deadline is running out on monday.... :-(

0

LVL 53

Expert Comment

ID: 21830718
>> But i do not care about optimizing the code

First of all, you should.

Second, what I said had nothing to do with optimizing code, but with making your own life (a lot) easier by writing proper code.

The point of assignments is to learn something. If you refuse to take my advice, and just continue on your own path, then I'm not sure what you're asking me to do here ...

>> so it should be: (tail-head)+1

What if head > tail ?

>> My head and my tails are parts of the queue, if its an int queue, its int, if its double queue its double if its QueueElement* Queue its QueueElement*

No. Take a closer look at how you use head and tail in your code. I'm starting to wonder whether you wrote the queue code yourself ... Did you ?
0

Author Comment

ID: 21830735
I wrote the code together with a friend, to be honest....
0

Author Comment

ID: 21830983
Here we go again.

int show me on which part of the array i am.
---
I do use the constructor with init the head and the tail by 0, with q() an element at the end of my array, at the tail.
---

---
bool isFull(){

cout << "Queue is full\n";
return true;
}
else{
return false
}
----

>>What if head > tail ?

Since my queue is static with a specific SIZE

i can check

{
}
else{
}

0

Author Comment

ID: 21831346
so i did work on, but i do have a few more errors to kill

Line 36
//expected primary expression before  '*' token  //expected primary expression before  ';' token

Line 47
//invalid     conversion from  'int' to 'QueueElement'

Thanks
``````#include <iostream>
using namespace std;

#define SIZE 20
#include "queueel.h"
class QueueClass {
int queue[SIZE];
public:

QueueClass(int, int);
~QueueClass();

void qu(QueueElement* newElement);
QueueElement* dequ();
int size();
bool isEmpty();
bool isFull();
};
QueueClass::~QueueClass () {}
QueueClass::QueueClass (int a, int b) {
tail = b;

}

void QueueClass::qu(QueueElement* newElement)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE){ tail = 0;
queue[tail] = QueueElement*;//expected primary expression before  '*' token  //expected primary expression before  ';' token
}
}

QueueElement* QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

bool QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;
}
bool QueueClass::isFull(){

cout << "Queue is full\n";
return true;
}
else{
return false;
}
}
``````
0

Author Comment

ID: 21833350
Line 36 gives out the following Error

invalid conversion from QueueElement* to int

In my Array, i wanna put a Pointer to QueueElement, but the programm expects an int... Why?

``````#include <iostream>
using namespace std;

#define SIZE 20
#include "queueel.h"
class QueueClass {
int queue[SIZE];
public:

QueueClass(int, int);
~QueueClass();

void qu(QueueElement* newElement);
int dequ();
int size();
bool isEmpty();
bool isFull();
};
QueueClass::~QueueClass () {}
QueueClass::QueueClass (int a, int b) {
tail = b;

}

void QueueClass::qu(QueueElement* newElement)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE){ tail = 0;
queue[tail] = newElement;//invalid conversion from QueueElement* to int
}
}

int QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

bool QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;
}
bool QueueClass::isFull(){

cout << "Queue is full\n";
return true;
}
else{
return false;
}
}
``````
0

LVL 53

Expert Comment

ID: 21833378
>> I do use the constructor with init the head and the tail by 0, with q() an element at the end of my array, at the tail.

Not in any code you posted. Can you point out where you do that ? Btw, are you sure that 0 is the correct value to initialize them to ?

>> bool isFull(){

ok. except that the cout should not really be there ...

>> {
>> }
>> else{
>> }

Does that give the correct value ? You need to be consistent with your choice of where head and tail point to ...

>>   queue[tail] = QueueElement*;//expected primary expression before  '*' token  //expected primary expression before  ';' token

I think the error is pretty clear, no ? What is that * doing there ?

>>   int queue[SIZE];

Why did you make it an array of int again ? I thought we already established that we need to store QueueElement*'s ?
0

Author Comment

ID: 21833443
>>Not in any code you posted. Can you point out where you do that ? Btw, are you sure that 0 is the correct value to initialize them to ?

I have to put my head and my tail somewhere... but i'm not sure whether to put them in the same place...

>> I think the error is pretty clear, no ? What is that * doing there ?

Corrected

>>   int queue[SIZE];

Corrected...

``````#include <iostream>
using namespace std;

#define SIZE 20
#include "queueel.h"
class QueueClass {
QueueElement* queue[SIZE];
public:

QueueClass(int, int);
~QueueClass();

void qu(QueueElement* newElement);
QueueElement* dequ();
int size();
bool isEmpty();
bool isFull();
};
QueueClass::~QueueClass () {}
QueueClass::QueueClass (int a, int b) {
tail = b;

}

void QueueClass::qu(QueueElement* newElement)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE){ tail = 0;
queue[tail] = newElement;//invalid conversion from QueueElement* to int
}
}

QueueElement* QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

bool QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;
}
bool QueueClass::isFull(){

cout << "Queue is full\n";
return true;
}
else{
return false;
}
}
``````
0

LVL 53

Expert Comment

ID: 21833489
>>  QueueClass(int, int);

What's the point of this constructor ? You should only have a default constructor that initializes head and tail to the correct values (be consistent).
0

Author Comment

ID: 21833555
Okay, then should the compiler write the constructor himself. But how to init head and tail correctly?

``````#include <iostream>
using namespace std;

#define SIZE 20
#include "queueel.h"
class QueueClass {
QueueElement* queue[SIZE];
public:

// QueueClass(int, int);
~QueueClass();

void qu(QueueElement* newElement);
QueueElement* dequ();
int size();
bool isEmpty();
bool isFull();
};
QueueClass::~QueueClass () {}
//QueueClass::QueueClass (int  a, int b) {
//  tail = b;
//
//}

void QueueClass::qu(QueueElement* newElement)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE){ tail = 0;
queue[tail] = newElement;//invalid conversion from QueueElement* to int
}
}

QueueElement* QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

bool QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;
}
bool QueueClass::isFull(){

cout << "Queue is full\n";
return true;
}
else{
return false;
}
}
``````
0

LVL 53

Expert Comment

ID: 21834058
>> Okay, then should the compiler write the constructor himself.

No, you should write it.

>> But how to init head and tail correctly?

You said you wrote the queue class. If so, you know how you defined head and tail. With that knowledge, you know how to correctly initialize them. Which element does head refer to, and which does tail refer to ?
0

Author Comment

ID: 21834144
To my knowledge, the head and the tail refer at the beginning to the first element of my static array....

That's why i thought i should init them with 0....

0

LVL 53

Expert Comment

ID: 21834398
>> the head and the tail refer at the beginning to the first element of my static array....

What do head and tail refer to when some data is in the queue ?
0

Author Comment

ID: 21834437
to the position in the queue, where data is put in
0

LVL 53

Expert Comment

ID: 21834691
>> to the position in the queue, where data is put in

?? What do head and tail refer to in the normal case ? Theree are two parts in the question : one for head, and one for tail ;)
0

Author Comment

ID: 21834728
The head refers to the first element i put into the queue and the tails refers to the last element i put in the queue. since we have an order we put the elements in, there are different positions
0

LVL 53

Expert Comment

ID: 21834781
>> and the tails refers to the last element i put in the queue.

Then how come that when the queue is empty, you say that both head and tail refer to position 0 ? That would mean there is one element in the queue (that is both the first and the last).
0

Author Comment

ID: 21834794
i got your point. so i do init the constructor with an empty body

QueueClass(){}

That should do?
0

LVL 53

Expert Comment

ID: 21834882
>> so i do init the constructor with an empty body

No. As I've said a few times already : you need to initialize head and tail to proper values. Which values for head and tail would signify an empty queue ?
0

Author Comment

ID: 21834888
Null?
0

LVL 53

Expert Comment

ID: 21834908
null ? ints cannot have a null value.

Take a look at the isEmpty method ... which values of head and tail would make it empty ?
0

Author Comment

ID: 21834919
if they both have the same values...
0

LVL 53

Expert Comment

ID: 21834937
>> if they both have the same values...

And is that consistent with what you said earlier ?

>> The head refers to the first element i put into the queue and the tails refers to the last element i put in the queue.
0

Author Comment

ID: 21834974
no ;-)

because my first queue should be empty, both have the same values, so a constructor with one parameter should be enough...
But i do not get the value i should put in my paramter

QueueClass(int a){

}
0

LVL 53

Expert Comment

ID: 21835008
>> no ;-)

So, how will you fix it ? How will you define head and tail ?

>> so a constructor with one parameter should be enough...

Why do you keep insisting on passing a parameter to the constructor ? There's no reason for that as I've said a few times already.
0

Author Comment

ID: 21835028
can we move that please to tommorow? i pretty tired...

but thanks a lot for your contious help :-)
0

LVL 53

Expert Comment

ID: 21835045
No problem. Have a good night :)
0

Author Comment

ID: 21835049
thanks!!!!
0

Author Comment

ID: 21835680
>>So, how will you fix it ? How will you define head and tail ?

If I do have a queue as an int array, we can assume that the array starts with 0 up to something.
If we put head and tail both to 0, there is one element in my queue
If i put head and tail both to -1, there is non element in my queue, therefore the queue is empty
If i q(), tail will go up to one, therefore i do have one element in my queue
if i q() again, tail go up to two, i do have two elements in my queue.

And if the constructor does not have a parameter list, i can only use an init list to init head an tail

Does this work out?
``````#include <iostream>
using namespace std;

#define SIZE 20
#include "queueel.h"
class QueueClass {
QueueElement* queue[SIZE];
public:

QueueClass();
~QueueClass();

void qu(QueueElement* newElement);
QueueElement* dequ();
int size();
bool isEmpty();
bool isFull();
};
QueueClass::~QueueClass () {}

void QueueClass::qu(QueueElement* newElement)
{
cout << "Queue is full\n";
return;
}
tail++;
if(tail==SIZE){ tail = 0;
queue[tail] = newElement;//invalid conversion from QueueElement* to int
}
}

QueueElement* QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

bool QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;
}
bool QueueClass::isFull(){

cout << "Queue is full\n";
return true;
}
else{
return false;
}
}
``````
0

LVL 53

Expert Comment

ID: 21836794
>> If i put head and tail both to -1, there is non element in my queue, therefore the queue is empty

Will that be compatible with your qu and dequ methods ? Ie. Try setting head and tail to -1, and then call the qu method. See what head and tail are set to now. Is that correct ?

>> And if the constructor does not have a parameter list, i can only use an init list to init head an tail

You can use the body of the constructor too, but init list is fine.
0

Author Comment

ID: 21836808
No, that's not correct.
Is my error probably that i did put head at the end and tail at the beginning?

Because you always talk about consistency?

0

LVL 53

Expert Comment

ID: 21836895
>> Because you always talk about consistency?

You need to choose where head is and where tail is, and then use that consistently in all code in the stack. Right now, each method uses a different interpretation of head and tail - that doesn't work out so well.

So, start by choosing how head and tail will be defined, and then modify all code according to it.
0

Author Comment

ID: 21836932
thanks. can we please go that through together. i know what i'm looking for, but i cannot connect all the dots correctly...

I do have a static array of lets say 20 elements.

Head is at the Ende, Tail in the front.

Is that the correct start?
0

LVL 53

Expert Comment

ID: 21836945
>> Head is at the Ende, Tail in the front.

Why ?
0

Author Comment

ID: 21836947
i can also switch it round, but in the end, it should not matter, should it?
0

LVL 53

Expert Comment

ID: 21836955
The head is always at the front - why else would you call it a head ?

Now, what will head refer to, and what will tail refer to ?
0

Author Comment

ID: 21836963
The Head refers to the beginning of the array, the tail is refering to the end of the array.

But as we discussed earlier yesterday, Head cannot be init with 0, because this means that there is an element in my queue

0

Author Comment

ID: 21836987
OK, i hopefully did change the heads and tail arround, can you please check that
``````#include <iostream>
using namespace std;

#define SIZE 20
#include "queueel.h"
class QueueClass {
QueueElement* queue[SIZE];
public:

QueueClass();
~QueueClass();

void qu(QueueElement* newElement);
QueueElement* dequ();
int size();
bool isEmpty();
bool isFull();
};
QueueClass::QueueClass():  head(-1) , tail(-1){} // -1 is not correct init list is fine
QueueClass::~QueueClass () {}

void QueueClass::qu(QueueElement* newElement) //ok
{
cout << "Queue is full\n";
return;
}
queue[head] = newElement;//invalid conversion from QueueElement* to int
}
}

QueueElement* QueueClass::dequ()
{
cout << "Queue is empty\n";
return 0;
}
tail++;
if(tail==SIZE) tail = 0;
}

int QueueClass::size()
{
int j=0;
for (; j<tail; j++){
}
return j;
}

bool QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;
}
//bool QueueClass::isFull(){
//
//    cout << "Queue is full\n";
//    return true;
//  }
//  else{
//  return false;
//  }
}
``````
0

LVL 53

Expert Comment

ID: 21837055
>> The Head refers to the beginning of the array, the tail is refering to the end of the array.

I mean : which element in the queue does head refer to ? And which does tail refer to ?
0

Author Comment

ID: 21837065
If the Queue is empty, both head and tail refer to the same element, because that is the condition which is implemented in empty()

To be honest.

I do feel more and more unsure whether I'm doing the right thing so i would be pleased if you can give me helping hand bei actually correction a code snippet with me, that i can use this confidence that this is correct to move on...

At the moment, i do see all the parts of my code wrong and false.... :-(
0

LVL 53

Expert Comment

ID: 21837073
>> because that is the condition which is implemented in empty()

That's a false premise. As I said earlier, FIRST decide how head and tail are defined, THEN implement it. Do not look at the current implementation of isEmpty. Just think about how you'll define head and tail.

If you want me to help you, then please follow my indications. This must be the tenth time that I'm trying to get you to define head and tail without going off on some wild goose chase.
0

Author Comment

ID: 21837092
>> If you want me to help you, then please follow my indications. This must be the tenth time that I'm trying to get you to define head >>and tail without going off on some wild goose chase.

I'm very thankfull that you try to help me, although you might be bored by telling some stupid jerk the millionth time to define the head and the tail. I do well understand that, but I cannot see or think of the solution to the problem you gave to me, and the result is a wild goose chase with to direction or movement at all...

So I beg you to give me some more hint... so that I can work on it together with you as a guide. Otherwise I would be lost...

0

LVL 53

Expert Comment

ID: 21837131
You said this earlier :

>> The head refers to the first element i put into the queue and the tails refers to the last element i put in the queue.

In order to advance, let's take this as the definition of head and tail. Please do NOT deviate from this definition from now on. This is the definition, and from now on we'll work with that.

Next step :

1) using this definition of head and tail, what does a full queue look like - ie. what relation will there be between head and tail ?

2) same question for an empty queue
0

Author Comment

ID: 21837152
Thanks.

We can also assume that the queue is an array of 20 element, the first element is on the position 0, the last ist 19. That make things less abstract for me

if the queue is FULL, the head is on the element 0, the tail is on the element 19
if the queue is EMPTY, there are no elements int the queue, therefor no head an tail.

Correct?
0

LVL 53

Expert Comment

ID: 21837171
>> if the queue is FULL, the head is on the element 0, the tail is on the element 19

The head is not necessarily at 0.

>> if the queue is EMPTY, there are no elements int the queue, therefor no head an tail.

head and tail HAVE to have a value. Which one ? Make sure that it doesn't clash with the definition of head and tail.
0

LVL 53

Expert Comment

ID: 21837181
I'm gonna be offline for a while now.
0

Author Comment

ID: 21837185
can we talk tommorow or today again?
0

Author Comment

ID: 21837192
>>head and tail HAVE to have a value. Which one ? Make sure that it doesn't clash with the definition of head and tail.

We only do have values from 0 to 19, right?
0

Author Comment

ID: 21837506
So, after some more work...

I changed my methods, i think did a lot of things wrong, hopefully its better now

Head and Tail are hopefully back in order, the compiler linked and did not find errors.

But i still do not know how to init them properly....
``````#include <iostream>
using namespace std;

#define SIZE 20
#include "queueel.h"
class QueueClass {
QueueElement* queue[SIZE];
public:

QueueClass();
~QueueClass();

void qu(QueueElement* newElement);
QueueElement* dequ();
int size();
bool isEmpty();

};
QueueClass::QueueClass():  head(-1) , tail(-1){} // -1 is not correct init list is fine
QueueClass::~QueueClass () {}

void QueueClass::qu(QueueElement* newElement) //ok
{
if(isEmpty()){
}
else{
tail++;
queue[tail] = newElement;
}
}

QueueElement* QueueClass::dequ()
{
if (isEmpty()) {return NULL;}
else
{
tail--;
}
}

int QueueClass::size()
{
if(isEmpty()) {return 0;}
else

return tail;
}

bool QueueClass::isEmpty()
{
cout << "Queue is empty\n";
return 1;
}
else return 0;
}
``````
0

LVL 53

Expert Comment

ID: 21840036
>> the compiler linked and did not find errors.

That doesn't mean that the program logic is ok.

In fact, it still isn't. You again have tried to go too fast.

You HAVE to get the answers to these questions correct. If you don't, there's no sense in continuing, because you will only waste time writing code that doesn't make sense.
0

Author Comment

ID: 21840050
Ok, thanks for your contiuning help,

>>>>head and tail HAVE to have a value. Which one ? Make sure that it doesn't clash with the definition of head and tail.

>>We only do have values from 0 to 19, right?

?

0

LVL 53

Expert Comment

ID: 21840052
>>We only do have values from 0 to 19, right?

I'm not asking about specific values - just conceptually. What's the relation between the head and tail values in both the empty and full queue cases ?
0

Author Comment

ID: 21840056
from my understanding, the queue is nothing else but a waiting line.
The Head is always in front of the tail
0

Author Comment

ID: 21840060
my browser just crashed..

If I q the first element, it is the head and at the same time the tail
If I q the second element, this one is behind the head and so on.
0

LVL 53

Expert Comment

ID: 21840066
>> If I q the first element, it is the head and at the same time the tail

Good.

>> If I q the second element, this one is behind the head and so on.

Ok.

>> If I deq the head, the second element becomes my head.....

Ok.

Those are the general cases. Now, the specific cases I asked about : a full and empty queue.

What happens if you queue 20 elements in your queue. What will head and tail be ?
What happens if you pop all elements from the queue. What will head and tail be ?
0

Author Comment

ID: 21840071
If I queue 20 elements in my queue, the head is on position 0 and the tail is on position 19

If I do pop all elements on the queue, there is no head and no tail, because the first element which i queue defines the head on the position it pushs in.

But I'm not shure if the head must be on position 0 or 1 or whereever
0

LVL 53

Expert Comment

ID: 21840085
>> If I queue 20 elements in my queue, the head is on position 0 and the tail is on position 19

As I said earlier : the head is not necessarily at 0.

But anyway, in your example : what's the relation between 0 and 19 ... How would you know if a queue is full based on the head and tail values ?

>> If I do pop all elements on the queue, there is no head and no tail,

There is always a head and a tail. Just do the exercise on paper : push a few elements on the queue, and then pop all of them. Take note of the head and tail values for each step.
0

Author Comment

ID: 21840101
>>But anyway, in your example : what's the relation between 0 and 19 ... How would you know if a queue is full based on the head and tail values ?

Tail - Head must be 19 as result

>>There is always a head and a tail. Just do the exercise on paper : push a few elements on the queue, and then pop all of them. Take >>note of the head and tail values for each step.

The Head is defined as being front of the tail.

If i do push one element on position 0, my head and my tail is 0.
If i do have none elements in my queue, i know that the head is in front of the tail

0

LVL 53

Expert Comment

ID: 21840105
>> Tail - Head must be 19 as result

Or, easier ?

What if head is not 0 ?

>> The Head is defined as being front of the tail.

What do you mean by "in front" ? Can you give an example ?
0

Author Comment

ID: 21840109
>>Or, easier ?
>>What if head is not 0 ?

OK, lets refine. The maximum result can be 19.

>>What do you mean by "in front" ? Can you give an example ?

[Elem1] Head on pos. 0, tail is on pos 0
[Elem2] Head on pos 0, tail is on pos 1
[Elem3]Head on pos 0, tail is on pos2
...

Since we do have a fifo structure, there the first element (head) which is put in is also the first element to pop out, the head must always be in front of tail

0

LVL 53

Expert Comment

ID: 21840117
>> OK, lets refine. The maximum result can be 19.

What does that change ? Suppose head is 5, what will tail be if the queue is full ?

>> [Elem1] Head on pos. 0, tail is on pos 0
>> [Elem2] Head on pos 0, tail is on pos 1
>> [Elem3]Head on pos 0, tail is on pos2

Now, pop these three elements off the queue, and list the head and tail values.
0

Author Comment

ID: 21840123
>>What does that change ? Suppose head is 5, what will tail be if the queue is full ?
The Tail can be 4

>>Now, pop these three elements off the queue, and list the head and tail values.

[Empty] Head is here, but since there is nothing in, we cannot tell about the position.... same to the tail
[Empty]
[Empty]
0

LVL 53

Expert Comment

ID: 21840125
>>  The Tail can be 4

The tail WILL be 4.

Now, what is the relation between tail and head if the queue is full ?

>> >>Now, pop these three elements off the queue, and list the head and tail values.

Pop the 3 elements out of the queue, one by one. And show one line for each pop.
0

Author Comment

ID: 21840129
The difference is 0 when full, if empty, its 19

>> [Elem1] Head on pos. 0, tail is on pos 0
>> [Elem2] Head on pos 0, tail is on pos 1
>> [Elem3]Head on pos 0, tail is on pos2

pop Elem3

[Elem1] Head on pos. 0, tail is on pos 0
[Elem2] Head on pos 0, tail is on pos 1

pop Elem2

[Elem1] Head on pos. 0, tail is on pos 0

pop Elem2

Head on pos 19, Tail on 0 ??????? can that be
0

LVL 53

Expert Comment

ID: 21840148
>> The difference is 0 when full,

How do you get that ? If head is at 5 and tail at 4, then the queue is full ... Is the difference 0 ?

>> pop Elem3

in a queue you have to pop the first element first ... ie. pop elem1 first. It's a FIFO structure, remember (first-in-first-out)
0

Author Comment

ID: 21840162

>>How do you get that ? If head is at 5 and tail at 4, then the queue is full ... Is the difference 0 ?

>>in a queue you have to pop the first element first ... ie. pop elem1 first. It's a FIFO structure, remember (first-in-first-out)

Thanks!

pop Elem1

[Elem2] Head on pos. 1, tail is on pos 2
[Elem3] Head on pos 1, tail is on pos 2

pop Elem2

[Elem3] Head on pos. 2, tail is on pos 2

pop Elem3
[Empty] Head's last pos was 2, tail's last pos was 2, so the new pos of the head if new elem is added is 2 again.
0

LVL 53

Expert Comment

ID: 21840231

ok. Don't forget the special case where head is 0.

>> pop Elem1

After pushing the third element, the queue was in this state, remember :

>> Head on pos 0, tail is on pos2

0

Author Comment

ID: 21840250
My first try for isEmpty()

``````bool isEmpty()
{
std::cout<<"true" <<std::endl;
return 1;

}
std::cout<<"true" <<std::endl;
return 1;
}
std::cout<<"true" <<std::endl;
return 1;
}
else{
std::cout<<"false" <<std::endl;
return 0;
}
}
``````
0

Author Comment

ID: 21840264
>>After pushing the third element, the queue was in this state, remember :

>>>> Head on pos 0, tail is on pos2

pop a

pop b

0

Author Comment

ID: 21840284
browser again :-(

pop c

head was on 2, tail was on 2
0

LVL 53

Expert Comment

ID: 21840333
>> My first try for isEmpty()

>> a head 0, tail 0
>> b head 0 tail 1
>> c head 0 tail 2

Euhm ... what does this notation mean ? At each given moment, the queue has only one head and tail value - it does NOT have a head and tail value for each element.

So, I'll get you started :

after pushing the first element : head = 0, tail = 0
after pushing the second element : head = 0, tail = 1
after pushing the third element : head = 0, tail = 2

after popping the first element : head = ?, tail = ?
after popping the second element : head = ?, tail = ?
after popping the third element : head = ?, tail = ?

You fill in the question marks.
0

Author Comment

ID: 21840355
thanks!

after pushing the first element : head = 0, tail = 0
after pushing the second element : head = 0, tail = 1
after pushing the third element : head = 0, tail = 2

after popping the first element : head = 1, tail = 2
after popping the second element : head = 2, tail = 2
after popping the third element : head = ?, tail = ? <<< if can't be 2,2 otherwise we have another element.

So we have to reset the queue to have no element on it. Head can be 0, and Tail can be Size-1

If we q , we increment the tail by 1 and do have again one element in the queue with head 0, tail 0
0

LVL 53

Expert Comment

ID: 21840380
>> after popping the third element : head = ?, tail = ? <<< if can't be 2,2 otherwise we have another element.

What would be the logical next step after these two ?

>> after popping the first element : head = 1, tail = 2
>> after popping the second element : head = 2, tail = 2
0

Author Comment

ID: 21840383

?
0

LVL 53

Expert Comment

ID: 21840401

Correct. Now what's the relation between head and tail for a full list ?
0

Author Comment

ID: 21840454
if we do have a full list and

head =0, tail =19 we do have the size as a result of tail-head.

but i do not fully undestand in which context you mean 'relation" obiously i do misunderstand this word in its context
0

LVL 53

Expert Comment

ID: 21840511
Do it for this specific case :

Just like you did it for a full list earlier :

>> >>How do you get that ? If head is at 5 and tail at 4, then the queue is full ... Is the difference 0 ?
>>
0

Author Comment

ID: 21840516
head 3  - tail 2 = 1

That means that the queue is empty.

if we do have head 2, tail 3, the queue is not empty.

so i can be done that:

return 1;
}
else{
return 0;
}
0

LVL 53

Expert Comment

ID: 21840540
>> head 3  - tail 2 = 1
>>
>> That means that the queue is empty.

Does it ? Take a look at your earlier observation about a full queue :

>> The difference is 1, if head-tail

See any similarities ?
0

Author Comment

ID: 21840577
i'm wrong, again. thats what i see which helps me to explore how much frustration i can take ;-)

To look at the end of the queue would certainly help me to see whether the queue is empty or not....
That is - i my limited point of view- the only chance to see if it is empty....

right?

We do have out queue with 20 elements, we popped 17 Elements so far

>> after popping the 18th element : head = 19, tail = 19
>> after popping the 19th element : head 0, tail = 19

Correct?
0

LVL 53

Expert Comment

ID: 21840592
Can you answer my question ?

>> >> head 3  - tail 2 = 1
>> >>
>> >> That means that the queue is empty.
>>
>> Does it ? Take a look at your earlier observation about a full queue :
>>
>> >> The difference is 1, if head-tail
>>
>> See any similarities ?
0

Author Comment

ID: 21840607
0

LVL 53

Expert Comment

ID: 21840613
>> >> See any similarities ?
0

Author Comment

ID: 21840620
The similarity i do see is that if the head is before the tail, we do have a full queue
0

LVL 53

Expert Comment

ID: 21840656
Do you see a similarity between :

>> >> head 3  - tail 2 = 1
>> >>
>> >> That means that the queue is empty.

and :

>> >> The difference is 1, if head-tail

(the latter for a full queue).
0

Author Comment

ID: 21840698
I maybe not catching your point here, maybe i do not see it here or i'm too stupid...

in one we dequeue until the head is behind the tail......

in another case, the head is behind the tail because we filled up our queue and circulated until we reached the postion in front of head....

That is all i can see here, the rest is too confusing for me.....
0

LVL 53

Expert Comment

ID: 21840730
I'll spell it out for you :

if head - tail = 1 then the queue is empty
if head - tail = 1 then the queue is full

See the similarity now ?
0

Author Comment

ID: 21840740
so that means that full and empty is the same?

0

LVL 53

Assisted Solution

Infinity08 earned 2000 total points
ID: 21840772
>> so that means that full and empty is the same?

That means that with the current information, you cannot make the distinction between a full and an empty queue. You need one more member in the queue : the current size of the queue.
0

Author Comment

ID: 21840795
thanks.....

so i do have to run through my queue with a for loop and look at each array, whether it contains QueueElement* or not

Something like this

int counter =0;
for(int i =o, i<size, i++){
if queue[QueueElement*]{
counter++
}
}

If counter==0 && head-tail==1 i can tell that the queue is empty... otherwise not

then i check if counter == size, then queue is full

That's why you insisted so hard on the full()...

0

Author Comment

ID: 21840797
thanks for all that guiding... i really appreciate...
0

Author Comment

ID: 21840910
That still leaves me with one questions... how to init the head and the tail...

If I queue an element, i do increment tail by one and put my new element to queue[tail]

If I dequeue the first element, i increment the head by one and return the head?

Does this works out?

0

Author Comment

ID: 21841224
0

LVL 53

Expert Comment

ID: 21842139
>> so i do have to run through my queue with a for loop and look at each array, whether it contains QueueElement* or not

Euh, no. Just keep a size member. If it's 0, then the queue is empty. If it has the maximum value, then the queue is full. You don't need to iterate.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. Aâ€¦
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [sâ€¦
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor anâ€¦
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
###### Suggested Courses
Course of the Month5 days, 14 hours left to enroll