Link to home
Start Free TrialLog in
Avatar of george08
george08

asked on

Build an abstract queueelement class and inheritance to classe queue to use it as an Object within a queue. No Idea

Here's another task i'm not able to solve without the power of all u fine people out here.

1. Create an abstract Class ObjectElement
2. Inheritance it (polymorphism with inclusion) to a class Queue to use object of QueueElement as an object of the queue.

Please help, i'm standing before a wall....

Please also check https://www.experts-exchange.com/questions/23470187/CPP-Class-Queue-FIFO-Template-Queue-Inheritance-of-Queue-Totally-stuck.html for the class queue and my former work on queues.

help is desperatly appreciated...

thanks


#include <iostream>
using namespace std;
 
class queueelement {
  double //some variables i'm what we need in that 
public:
  //Some Methods for the Object I'm not sure what is needed
 
};
 
class queue : public queueelement {
}

Open in new window

Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Hello again george08 :)

Start off by having a look at my response to the following Q as you might find it useful (it relates to using abstract classes and dynamic plymorphism)...

http:Q_23466400.html#21739286

After you've read that post back here with any specific Qs on what doubts you have and we can take it from there.
Avatar of george08
george08

ASKER

Here we go... That should be my abstract class. I know about how to inherite, but i do have no clue how to inherite this class to the class queue, so that i can use my queueelemnt as a part of the queue.

Any ideas?
class QueueElement {
 public:
  QueueElement *next;
  double data;
 public:
 
  QueueElement(int d) {
    data=d;
    next=null;
  }
 
  ~QueueElement() {
    printf("~QueueElement\n");
  }
 
  virtual setData( d) =0;
  //{
  //  data=d;
  //}
 
  virtual QueueElement::getData() =0;
//  {
//    return data;
//  }
 
  QueueElement *getNext() =0;
  //{
  //  return next;
  //}
 
 
};

Open in new window

You inherit an abstract class (sometimes called an interface) in the same way as any other class. The only different is you must implement all the pure virtual functions (the functions that you assign 0). In this case you must implement setData getData and getNext in your sub-class.

Have a read of this: http://www.cplusplus.com/doc/tutorial/polymorphism.html

BTW: Can I just remind you that the Q to which this links is still open. It would be nice if you could take 2 mins to close it if you are happy with the answers you've been given so far.

Thanks.
Here's a try how i should solve this...

class Queue: public class QueueElement{

///con and destructors

};

v\oid QueueClass::qu(some reference to Qeueelement) ///would that work this way?
{
  if(tail+1==head || (tail+1==SIZE && !head)) {
    cout << "Queue is full\n";
    return;
  }
  tail++;
  if(tail==SIZE) tail = 0; // cycle around
  queue[tail] = num;
}
I'm sorry george08 but I don't see what that has to do with polymorphism and abstract classes :)
to start first.

i do not want to offend anyone here arround, i highly appreciate all the help i can get. mayby i'm not the smartest kid arround here, all i ask is some more help (after i already got so much). my other problem is, that i'm not totally good in programming and cpp, i know java a bit and trying to work my way in cpp. but actually it does not work so well, as you all can see arround here.

second.

is the code snippet i posted above an abstract class to start things of?

i highly appreciate any comments, but i do have a time issue and my head is suffering from a bad headache arround here... sorry.
ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
That's a great start - i work on it, if questions pop up, i give u a call
>> That's a great start - i work on it, if questions pop up, i give u a call
Sure thing, I'm always here (well, not always -- I do sleep sometimes, but you know what I mean :) )

Good luck my friend :)
So, this might work out, shouldn't it?

I do have the inheritance, and with the pointer to an object of the class Queueelement, i can put objects to my queue.

See the Code Snippet?
#include <iostream>
using namespace std;
 
#define SIZE 20
 
class QueueClass: public Queueelement
class QueueClass {
  int queue[SIZE];
  int head, tail;
 
  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;
 }
 
int main()
{
  QueueClass queue1;
  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);
  }
  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

You seem to have quite a few syntax errors. Are you posting your code for me to help you fix these or just to review your progress so far?

You're not using the class in main in anyway that is polymorphic. To do so you need to define a reference or pointer of the base class type to point to the sub-class type. It is the fact that you have this base class pointer or reference behaving in the context of the derived class that constitutes polymorphism. So far you have no code that demonstrates this. Try changing line 64/65 to the following

QueueClass queue1_object;
QueueElement & queue1 = queue1;  // Take a base class reference to the sub class. Accessing sub class via base class reference will demonstrate polymorphic behavior
Thanks for your answer. :-)

It was more like a question about my thoughts about the whole issue go in the right direction, but i'm also pleased if we could together terminate all these annoying errors.

Last but not least, i do wonder what are the advantages of doing such a solution, if i use a template as i did before i can achieve the same results... or i'm i totally wrong?
Templates are used for implementing generic behavior for unrelated types. Your template code allowed you to implement a queue generically for many different unrelated types. This is called static polymorphism because the context of what's being done is resolved as compile time.

Late binding, the mechanism use for dynamic polymorphism, is used when you want to provide specialized behavior for related types. This polymorphic interface allows you to inherit an abstract queue behavior and create a new queue with specialized behavior.

This article may help to assist your understanding of when to use each: http://www.ishiboo.com/~nirva/c++/eff/EC/EI41_FR.HTM
Thank you.
But again my question above?

The code snippet I postet above should be close to a possible solution?

>> The code snippet I postet above should be close to a possible solution?
There is not enough in that snippet to gague this but since you are not using polymorphic behavior in main the current answer is no.

Did you read up on polymorphism like I suggested in {http:#21770945}?
I did look on the page you gladly suggested, but i'm unable to transfer the knowlegde i learn there to my actuael problem...


//abstract class
 
class QueueElement {
 public:
  QueueElement *next;
  double data;
 public:
 
  QueueElement(int d) {
    data=d;
    next=null;
  }
 
  ~QueueElement() {
    printf("~QueueElement\n");
  }
 
  virtual setData( d) =0;
  {
    data=d;
  }
 
  virtual QueueElement::getData() =0;
  {
    return data;
  }
 
  QueueElement *getNext() =0;
  {
    return next;
  }
 
 
};
//// queuemain.cc
 
#include <iostream>
using namespace std;
 
#define SIZE 20
 
class QueueClass: public Queueelement
{ //expected class name before { token
  public:
  int queue[SIZE];
  int head, tail;
 
  QueueClass();
  void qu(Queueelement* newElement); //Queueelement has not been declared
  int dequ();
  int size();
  int isEmpty();
};
 
QueueClass::QueueClass()			//declared private
{
  head = tail = 0;
}
 
void QueueClass::qu(Queueelement* newElement)  ///variable or field is declared void //int class Queue is not a static member of class 'QueueClass' //Queueelement is not declared in the scope //newElement was not declared in scope
{												// , or ; expected before {
  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;
 }
 
int main()
{
  QueueClass queue1;   
QueueElement * queue1 = &queue1_object;  
queue1-> setData(1.0); //has non Pointer Typ
queue1-> getData(); //has non Pointer Typ
  
  
  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);
  }
  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

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
george08,

Can I also point out that {http:Q_23470187.html} is still not finalized. You'll see that modus_operandi has made a request for you to consider finalizing it. If you need help with that just post back and respond to him and he will guide you through the process.

george08, it is very important you close out your questions once its been answered. You will not keep the attention of experts for very long (and this includes me) if you don't take the time to close your questions and award credit to those who have contributed. Although we are all volunteers on Experts Exchange we do appreciate the points you award us. As well as augmenting our rating (so that other Askers can gauge how much credence they might give to an expert -- as Vee_Mod suggested in the other thread) we also get t-shirts and other goodies when we reach various levels within the points raking system. I would ask you and would really appreciate it if you could just take 2 mins to review the previous thread and close it out. I have made a recommendation within that thread as to what answers I believe should be accepted. You are free to ignore this and choose whatever you think best but I do believe the recommendations I have made are fair and ensures the best possible answers for the PAQ (Previously Answered Questions) database.

Many thanks.

-Rx.
Thanks for all the support.

Here we go to my errors in the code snippet below and my questions to it, which - i might point out do not fully understand although doing an extensive google search...

Line 7 //Expect Class Name before { Token  //G08: what's wrong with that, the class names are correct?
Line 14 //QueueElement has not been declared //G08: but i only define the object of the class QueueElement in the main methode? See also below.
Line 25 //QueueElement was not declared in the scope
Line 25 //newelement was not declared in the scope
Line 26 //Expected , or ; before the {token



@Rx:
With your good example and your Links i do now understand better the princip of inheritance and polymorphism.

I ask for guidance in closing my old case, thanks a lot. should be done soon enough.
#include <iostream>
 
using namespace std;
 
#define SIZE 20
 
class QueueClass: public QueueElement{   
  private:
  int queue[SIZE];
  int head, tail;
 
 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

You have not included the header for QueueElement so the compiler knows nothing of it.
That's it.

I' down to some cryptic error i really do not understand.

/usr/lib/......../libcygwin.a(libcmain):: undefined reference to '_WinMain@16'
collect2: ld return 1 exit status



I do know that return 0 at the end shows if everything is fine, and that any other than 0 is no good.
#include <iostream>
using namespace std;
 
#define SIZE 20
 
class QueueClass {
  int queue[SIZE];
  int head, tail;
public:
  QueueClass();
  void qu(int num);
  int dequ();
  int size();
  int isEmpty();
};
 
QueueClass::QueueClass()
{
  head = tail = 0;
}
 
void QueueClass::qu(int num) // zeiger auf queueelemnt queuelement* newelement //// alles int auf quee element queue zeiger auf queue elemnt bei template....
{
  if(tail+1==head || (tail+1==SIZE && !head)) {
    cout << "Queue is full\n";
    return;
  }
  tail++;
  if(tail==SIZE) tail = 0; // cycle around
  queue[tail] = num;
}
 
int QueueClass::dequ()
{
  if(head == tail) {
    cout << "Queue is empty\n";
    return 0;                    // or some other error indicator
  }
  head++;
  if(head==SIZE) head = 0;       // cycle around
  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;
 }
 
int main()
{
  QueueClass queue1;
  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);
  }
  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;
}
 
int main()
{
CRectangle rect;
  CTriangle trgl;
  CPolygon * ppoly1 = &rect;
  CPolygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  cout << ppoly1->area() << endl;
  cout << ppoly2->area() << endl;
  return 0;
 
 
 
QueueClass queue_object;   
QueueElement * queue1 = &queue_object;  
queue1-> setData(1.0); 
queue1-> getData(); 
 
  
  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);
  }
  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

That means you have tried to build this as a Windows rather than a Console program. The entry point for a Console program is main() for a Windows program it is WinMain. You'll need to create a new project for a Console and copy your code over or change the existing project to be a Console project -- not 100% how easy that is to be honest :)
ok, but the code is right and there are no other errors whatsoever? I mean, compilerwise....
If it gets to the linking phase it must compile :)
so it works! wow, thanks for all that guiding evilrix :-)
No worries sir.
Hey, as i realized, my old question was not closed. Maybe i did something wrong with my request? Maybe some more experienced user can help me with that problem?

Beside that, i do have one more questions.

I do have my abstract h from which i want to inheritate two more classes, lets say QueueElementInt and QueueelementFloat.

With Polymorphism, i wanna use these QueueElement in my class Queue, but without inheritate my QueueElement to Queue

class QueueClass: public QueueElement{ // that i do not wanna use.


It my thought and my code still correct?

Thanks for your Help!


//abstract.h
 
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;
  }
};
 
//////////Queue
 
 
#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

>> Hey, as i realized, my old question was not closed. Maybe i did something wrong with my request
You have to select the answers you wish to close the Q. I@ve provided you links to help and told you to contact a moderator for help if you need it. You didn't response to modus_operandi in the other thread. They can only help you if you ask for it.

I see you have opened another thread now and Infinity08 is helping you there.
Maybe u can also join us, would be nice, thanks.
I am monitoring but Infinity08 is a highly skilled expert (and a friend)... I know he'll be more than capable of assisting you without me :)
I never doubt that... i apreciate all of that very much