Solved

C++ Inheritance Polymorphism

Posted on 2008-06-19
147
450 Views
Last Modified: 2010-05-18
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 head, tail;

  int num;

 

 public:

  QueueClass();

  void qu(QueueElement* newElement);  

  int dequ();

  int size();

  int isEmpty();

};

 

QueueClass::QueueClass()			

{

  head = tail = 0;

}

 

void QueueClass::qu(QueueElement* newElement)  

{												

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return;

  }

  tail++;

  if(tail==SIZE) tail = 0; 

  queue[tail] = num;

}

 

int QueueClass::dequ()

{

  if(head == tail) {

    cout << "Queue is empty\n";

    return 0;                    

  }

  head++;

  if(head==SIZE) head = 0;     

  return queue[head];

}

 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }

 

 int QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 

 }

Open in new window

0
Comment
Question by:george08
  • 83
  • 63
147 Comments
 
LVL 53

Accepted Solution

by:
Infinity08 earned 500 total points
Comment Utility
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

by:george08
Comment Utility
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

by:george08
Comment Utility
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 500 total points
Comment Utility
>> 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

by:Infinity08
Comment Utility
>> 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

by:Infinity08
Comment Utility
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

by:george08
Comment Utility
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
{  
      if(tail+1==head || (tail+1==SIZE && !head)) {
            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.

But in the Meantime, please help me out on my other objective. Thanks!


///queuet.h
 

#ifndef QUEUET_H

#define QUEUET_H

 

#include <iostream>

using namespace std;

 

#define SIZE 20

 

template <typename T>

class QueueClass

{ 

 

  T queue[SIZE];

      T head, tail;

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

	head = a; 

	tail = b; 				

 

}

 

template <typename T> 

 

void QueueClass<T>::qu(T num) 		//init declarator before < token //expected ; befor < token

{  

	if(tail+1==head || (tail+1==SIZE && !head)) {

		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

{

	if(head == tail) {

		cout << "Queue is empty\n";

		return 0;                   

	}

	head++;

	if(head==SIZE) head = 0;       

	return queue[head];

}

 

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

	if(head == tail) {

		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;

}

Open in new window

0
 

Author Comment

by:george08
Comment Utility
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;

 

 

};

Open in new window

0
 

Author Comment

by:george08
Comment Utility
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;

	}

	};

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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.


Please see below. Thanks.



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

	}

	

	

	};

Open in new window

0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 500 total points
Comment Utility
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

by:george08
Comment Utility
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

by:Infinity08
Infinity08 earned 500 total points
Comment Utility
>> 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

Please, read through that, and if anything is not clear, ask about it here.


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

by:george08
Comment Utility
>>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' reading, please see also above for my question about the propper return type


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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Infinity08 earned 500 total points
Comment Utility
>> 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

by:george08
Comment Utility
Thats it

Convert your class queue so that instead of templates now inheritance
(Inclusionspolymorphism). Write about an abstract
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; 				

	head = a; 

 

}

 

template <typename T> 

 

void QueueClass<T>::qu(T num) 		

{  

	if(tail+1==head || (tail+1==SIZE && !head)) {

		cout << "Queue is full\n";

		return;

	}

	tail++;

	if(tail==SIZE) tail = 0; 

	queue[tail] = num;

}

 

template <typename T> 

 

T QueueClass<T>::dequ()		

{

	if(head == tail) {

		cout << "Queue is empty\n";

		return 0;                   

	}

	head++;

	if(head==SIZE) head = 0;       

	return queue[head];

}

 

template <typename T> 

T QueueClass<T>::size()

{ 							

	T j=0;

	for (; j<tail; j++){

	}

	return j;

}

 

template <typename T> 

 

T QueueClass<T>::isEmpty()

{  				

	if(head == tail) {

		cout << "Queue is empty\n";

		return 1;

	}

	else return 0;

}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
google translate did a poor job on this

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

Author Comment

by:george08
Comment Utility
"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

by:george08
Comment Utility
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;

	}

	

	

	};

Open in new window

0
 

Author Comment

by:george08
Comment Utility
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?

Please do not laugh about me ;-)
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
>>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....

About the assignment:

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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
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

by:george08
Comment Utility
thanks for your time and patience... good night
0
 

Author Comment

by:george08
Comment Utility
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;

	}

	

	

	};

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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 head, tail;

  int num;

 

 public:

  QueueClass();

  void qu(QueueElement* newElement);  

  int dequ();

  int size();

  int isEmpty();

};

 

QueueClass::QueueClass()			

{

  head = tail = 0;

}

 

void QueueClass::qu(QueueElement* newElement)  

{												

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return;

  }

  tail++;

  if(tail==SIZE) tail = 0; 

  queue[tail] = num;

}

 

int QueueClass::dequ()

{

  if(head == tail) {

    cout << "Queue is empty\n";

    return 0;                    

  }

  head++;

  if(head==SIZE) head = 0;     

  return queue[head];

}

 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }

 

 int QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 

 }

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
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

by:george08
Comment Utility
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) { 		

	head = a; 

	tail = b; 				

 

}

 
 

 

void QueueClass::qu(QueueElement* num) 		

{  

	if(tail+1==head || (tail+1==SIZE && !head)) {

		cout << "Queue is full\n";

		return;

	}

	tail++;

	if(tail==SIZE) tail = 0; 

	queue[tail] = num;

}

 

 

 

QueueElement QueueClass::dequ()		

{

	if(head == tail) {

		cout << "Queue is empty\n";

		return 0;                   

	}

	head++;

	if(head==SIZE) head = 0;       

	return queue[head];

}

 
 

int QueueClass::size()

{ 							

	int j=0;

	for (; j<tail; j++){

	}

	return j;

}

 
 

 

boolean QueueClass::isEmpty()

{  				

	if(head == tail) {

		cout << "Queue is empty\n";

		return true;

	}

	else return false;

}

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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];

      QueueElement head, tail;

public:

 

 QueueClass();

 ~QueueClass(){};

 

 

  void qu(QueueElement* num);

 

  void dequ();

  int size();

  boolean isEmpty();

};

 

#endif

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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.


>>       QueueElement head, tail;

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

by:george08
Comment Utility
>>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.
Point taken, see also codesnippet



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

by:george08
Comment Utility
boolean is bool

0
 

Author Comment

by:george08
Comment Utility
How can i include my QueueElement to my Queue.h?
#ifndef QUEUE_H

#define QUEUE_H

 
 

 

#define SIZE 20

 

class QueueClass

{

 

  QueueElement* queue[SIZE];

      QueueElement* head, tail;

public:

 

 QueueClass();

 ~QueueClass(){};

 

 

  void qu(QueueElement* num);

 

  void dequ();

  int size();

  bool isEmpty();

};

 

#endif

Open in new window

0
 

Author Comment

by:george08
Comment Utility
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];

      QueueElement* head, tail;

public:

 

 QueueClass();

 ~QueueClass(){};

 

 

  void qu(QueueElement* newElement);

 

  QueueElement* dequ();

  int size();

  bool isEmpty();

};
 

 

QueueClass::QueueClass()            

{

 

}

 

void QueueClass::qu(QueueElement* newElement)  

{                                                

  if(tail+1==head || (tail+1==SIZE && !head)) {

    std::cout << "Queue is full\n";

    return;

  }

  tail++;

  if(tail==SIZE) tail = 0;

  queue[tail] = newElement;

}

 

QueueElement* QueueClass::dequ()

{

  if(head == tail) {

    std::cout << "Queue is empty\n";

    return 0;                    

  }

  head++;

  if(head==SIZE) head = 0;     

  return queue[head];

}

 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }

 

 bool QueueClass::isEmpty()

 {

    if(head == tail) {

    std::cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 

 }

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> >>   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 :

>> >>       QueueElement head, tail;
>>
>> 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

by:george08
Comment Utility
>>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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
>>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

by:george08
Comment Utility
>>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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
I wrote the code together with a friend, to be honest....
0
 

Author Comment

by:george08
Comment Utility
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(){

  if(tail+1==head || (tail+1==SIZE && !head)) {
    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

if(head<tail)
{
int = (tail-head)+1;
}
else{
int = (SIZE-head)+tail+1
}

0
 

Author Comment

by:george08
Comment Utility
so i did work on, but i do have a few more errors to kill

please see the code snippet

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

      int head, tail;

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) {

  head = a;

  tail = b;
 

}
 

void QueueClass::qu(QueueElement* newElement)

{

  if(tail+1==head || (tail+1==SIZE && !head)) {

    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()

{

  if(head == tail) {

    cout << "Queue is empty\n";

    return 0;                    

  }

  head++;

  if(head==SIZE) head = 0; //invalid     conversion from  'int' to 'QueueElement'

  return queue[head];

}
 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }
 

 bool QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 }

 bool QueueClass::isFull(){
 

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return true;

  }

  else{

  return false;

  }

  }

Open in new window

0
 

Author Comment

by:george08
Comment Utility
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];

      int head, tail;

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) {

  head = a;

  tail = b;
 

}
 

void QueueClass::qu(QueueElement* newElement)

{

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return;

  }

  tail++;

  if(tail==SIZE){ tail = 0; 

  queue[tail] = newElement;//invalid conversion from QueueElement* to int

  }

}
 

int QueueClass::dequ()

{

  if(head == tail) {

    cout << "Queue is empty\n";

    return 0;                    

  }

  head++;

  if(head==SIZE) head = 0; //invalid     conversion from  'int' to 'QueueElement'

  return queue[head];

}
 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }
 

 bool QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 }

 bool QueueClass::isFull(){
 

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return true;

  }

  else{

  return false;

  }

  }

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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 ...


>> if(head<tail)
>> {
>> int = (tail-head)+1;
>> }
>> else{
>> int = (SIZE-head)+tail+1
>> }

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

by:george08
Comment Utility
>>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];

      int head, tail;

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) {

  head = a;

  tail = b;
 

}
 

void QueueClass::qu(QueueElement* newElement)

{

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return;

  }

  tail++;

  if(tail==SIZE){ tail = 0; 

  queue[tail] = newElement;//invalid conversion from QueueElement* to int

  }

}
 

QueueElement* QueueClass::dequ()

{

  if(head == tail) {

    cout << "Queue is empty\n";

    return 0;                    

  }

  head++;

  if(head==SIZE) head = 0; 

  return queue[head];

}
 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }
 

 bool QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 }

 bool QueueClass::isFull(){
 

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return true;

  }

  else{

  return false;

  }

  }

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>>  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

by:george08
Comment Utility
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];

      int head, tail;

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) { 

//  head = a;

//  tail = b;

//

//}
 

void QueueClass::qu(QueueElement* newElement)

{

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return;

  }

  tail++;

  if(tail==SIZE){ tail = 0; 

  queue[tail] = newElement;//invalid conversion from QueueElement* to int

  }

}
 

QueueElement* QueueClass::dequ()

{

  if(head == tail) {

    cout << "Queue is empty\n";

    return 0;                    

  }

  head++;

  if(head==SIZE) head = 0; 

  return queue[head];

}
 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }
 

 bool QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 }

 bool QueueClass::isFull(){
 

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return true;

  }

  else{

  return false;

  }

  }

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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....

If that is not correct, please give me additional hints....
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
to the position in the queue, where data is put in
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
i got your point. so i do init the constructor with an empty body

QueueClass(){}

That should do?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
Null?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
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
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 

Author Comment

by:george08
Comment Utility
if they both have the same values...
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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){

head, tail = a;
}
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
can we move that please to tommorow? i pretty tired...

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

Expert Comment

by:Infinity08
Comment Utility
No problem. Have a good night :)
0
 

Author Comment

by:george08
Comment Utility
thanks!!!!
0
 

Author Comment

by:george08
Comment Utility
>>So, how will you fix it ? How will you define head and tail ?

int head, 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];

      int head, tail;

public:

 

QueueClass(); 

  ~QueueClass();

 
 

  void qu(QueueElement* newElement);

  QueueElement* dequ();

  int size();

  bool isEmpty();

  bool isFull();

};

QueueClass::QueueClass():  head(-1) , tail(-1){}

QueueClass::~QueueClass () {}
 
 

void QueueClass::qu(QueueElement* newElement)

{

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return;

  }

  tail++;

  if(tail==SIZE){ tail = 0; 

  queue[tail] = newElement;//invalid conversion from QueueElement* to int

  }

}
 

QueueElement* QueueClass::dequ()

{

  if(head == tail) {

    cout << "Queue is empty\n";

    return 0;                    

  }

  head++;

  if(head==SIZE) head = 0; 

  return queue[head];

}
 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }
 

 bool QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 }

 bool QueueClass::isFull(){
 

  if(tail+1==head || (tail+1==SIZE && !head)) {

    cout << "Queue is full\n";

    return true;

  }

  else{

  return false;

  }

  }

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> Head is at the Ende, Tail in the front.

Why ?
0
 

Author Comment

by:george08
Comment Utility
i can also switch it round, but in the end, it should not matter, should it?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
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

by:george08
Comment Utility
The Head refers to the beginning of the array, the tail is refering to the end of the array.


Head[][][][][][][][][][][]Tail

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

by:george08
Comment Utility
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];

      int head, tail;

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

{

  if(head+1==tail || (head+1==SIZE && !tail)) { //ok //head is tail before and tail is head before

    cout << "Queue is full\n";

    return;

  }

  head++;

  if(head==SIZE){ head = 0; 

  queue[head] = newElement;//invalid conversion from QueueElement* to int

  }

}
 

QueueElement* QueueClass::dequ()

{

  if(tail == head) {

    cout << "Queue is empty\n";

    return 0;                    

  }

  tail++;

  if(tail==SIZE) tail = 0; 

  return queue[head];

}
 

int QueueClass::size()

{

    int j=0;

  for (; j<tail; j++){

  }

  return j;

  }
 

 bool QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 }

 //bool QueueClass::isFull(){

//

//  if(tail+1==head || (tail+1==SIZE && !head)) {

//    cout << "Queue is full\n";

//    return true;

//  }

//  else{

//  return false;

//  }

  }

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
>> 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

by:Infinity08
Comment Utility
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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:Infinity08
Comment Utility
I'm gonna be offline for a while now.
0
 

Author Comment

by:george08
Comment Utility
can we talk tommorow or today again?
0
 

Author Comment

by:george08
Comment Utility
>>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

by:george08
Comment Utility
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];

      int head, tail;

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()){

	queue[head]=queue[tail]=newElement;

	}

	else{

	tail++;

	queue[tail] = newElement;

	}

}
 

QueueElement* QueueClass::dequ()

{

  if (isEmpty()) {return NULL;}

  else

  {

  tail--;

  return queue[tail]; //or head?

  }

}
 

int QueueClass::size()

{

	if(isEmpty()) {return 0;}

	else

	

	return tail;

}
 

 bool QueueClass::isEmpty()

 {

    if(head == tail) {

    cout << "Queue is empty\n";

    return 1;

    }

    else return 0;

 }

Open in new window

0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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.

Please, go back to this post, and answer it the way I asked : http:#21837131

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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>>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

by:george08
Comment Utility
from my understanding, the queue is nothing else but a waiting line.
The Head is always in front of the tail
0
 

Author Comment

by:george08
Comment Utility
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.
If I deq the head, the second element becomes my head.....
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
>>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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
>>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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
>>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

by:Infinity08
Comment Utility
>>  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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility


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

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


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

by:Infinity08
Comment Utility
>> The difference is 1, if head-tail or -1 if tail-head

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

Now, start popping, and adjusting head and tail accordingly.
0
 

Author Comment

by:george08
Comment Utility
My first try for isEmpty()


bool isEmpty()

{

  if (head>tail){

  head-tail ==1;

 std::cout<<"true" <<std::endl;

 return 1;
 

 }

 else if(head<tail){

 tail-head==-1;

 std::cout<<"true" <<std::endl;

 return 1;

 }

 else if(head==0, tail==0){

 std::cout<<"true" <<std::endl;

 return 1;

 }

 else{

 std::cout<<"false" <<std::endl;

 return 0;

 }

}

Open in new window

0
 

Author Comment

by:george08
Comment Utility
>>After pushing the third element, the queue was in this state, remember :

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

>>Now, start popping, and adjusting head and tail accordingly.


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

pop a

b head 1, tail 1
c head 1, tail 2

pop b

c head 2, tail 2

0
 

Author Comment

by:george08
Comment Utility
browser again :-(

pop c

head was on 2, tail was on 2
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> My first try for isEmpty()

Don't get ahead of yourself. First answer both questions.


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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
head =3, tail =2

?
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> head =3, tail =2

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

Author Comment

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
Do it for this specific case :

>> head =3, tail =2

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 ?
>>
>> The difference is 1, if head-tail or -1 if tail-head
0
 

Author Comment

by:george08
Comment Utility
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:

if((head>tail)&&(head-tail==1)){

return 1;
}
else{
return 0;
}
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> 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

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
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

by:george08
Comment Utility
1 means the the queue is full to answer your question.
0
 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
>> >> See any similarities ?
0
 

Author Comment

by:george08
Comment Utility
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

by:Infinity08
Comment Utility
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