Hi guys,

I have a question concerning the following code I have written for a final project in an entry level C++ course. My task requires 3 level hierarchy (which i have) and use of polymorphism. The program works in this state, but I dont think I am actually exercising any polymorphic function and I am struggling to do it correctly. Various errors like C2228 or C2227 appear when I try to call a virtual function through an object.
I am not very experienced, that's why I am asking for your help.

Btw, this is like a toolkit for table booking and bill processing in a restaurant for example.

10X in advance!

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <fstream>
using namespace std;
struct Menu
{
	int soup,salad, beefsteak, pizza, pancake, cake, soda, whisky;
};
class Client 
{
public:
	string name;
	Menu order;
	int table_number;
	string type;
	double bill;
	
	Client(void)
	{
		name="";
		table_number=0;
		type="";
		bill=0.0;
	}
};

int tables_booked[20];
Client clients[20];
int number_clients;


class Table:public Client
{
public:
	
	Table(void)
	{
		number_clients=0;
	}

	virtual void addClient(void)
	{
		clients[number_clients].order.soup=0;
		clients[number_clients].order.salad=0;
		clients[number_clients].order.beefsteak=0;
		clients[number_clients].order.pizza=0;
		clients[number_clients].order.pancake=0;
		clients[number_clients].order.cake=0;
		clients[number_clients].order.soda=0;
		clients[number_clients].order.whisky=0;
		cout<<"\nEnter client's name:";
		cin>>clients[number_clients].name;
	}

	void ShowList(void)
	{
		cout<<"________________________________________________________________________________";
		cout<<"\nNumber    Name                        Table number         Bill      Type";
		for (int i=0;i<number_clients;i++)
		{
			cout<<"\n"<<setw(3)<<i<<setw(30)<<clients[i].name<<setw(15)<<clients[i].table_number<<setw(15)<<clients[i].bill<<setw(12)<<clients[i].type<<endl;
		}
		system("pause"); 
	}
	
	virtual void addBill(void)
	{
		int m,choice=0,quantity=0;
		do
		{
			ShowList();
			cout<<"\nEnter client's number according to the list:";
			cin>>m;
			if ((m<0)||(m>=number_clients))
			{
				cout<<"\nNo such number in the list...Try again.";
				system("pause");
			}
		}

		while ((m<0)||(m>=number_clients));
		cout <<"\nWhat did the client order from the menu?";
		cout<<"\n0.Soup";
		cout<<"\n1.Salad";
		cout<<"\n2.Beefsteak";
		cout<<"\n3.Pizza";
		cout<<"\n4.Pancake";
		cout<<"\n5.Cake";
		cout<<"\n6.Soda";
		cout<<"\n7.Whisky";
		cout<<"\nEnter: 0,1,2,3,4,5,6 or 7:";
		do{
			cin>>choice;
			if ((choice<0)||(choice>7)) 
			{
				cout<<"\nInvalid choice. Try again.";
				system("pause");
			}
		}
		while ((choice<0)||(choice>7));
		switch (choice)
		{
		case 0:
			{
				cout<<"\nEnter quantity:";
				cin>>quantity;				
				clients[m].bill+=quantity*4;
				cout<<"\n"<<quantity*4<<" lv. were added to the bill of "<<clients[m].name<<".";
				system("pause");
			}
			break;
		case 1:
			{
				cout<<"\nEnter quantity:";
				cin>>quantity;
				clients[m].bill+=quantity*6;
				cout<<"\n"<<quantity*6<<" lv. were added to the bill of "<<clients[m].name<<".";
				system("pause");
			}
			break;
		case 2:
			{
				cout<<"\nEnter quantity:";
				cin>>quantity;					
				clients[m].bill+=quantity*15;
				cout<<"\n"<<quantity*15<<" lv. were added to the bill of "<<clients[m].name<<".";
				system("pause");
			}
			break;
		case 3:
			{
				cout<<"\nEnter quantity:";
				cin>>quantity;
				clients[m].bill+=quantity*10;
				cout<<"\n"<<quantity*10<<" lv. were added to the bill of "<<clients[m].name<<".";
				system("pause");
			}
			break;
		case 4:
			{
				cout<<"\nEnter quantity:";
				cin>>quantity;
				clients[m].bill+=quantity*3;
				cout<<"\n"<<quantity*3<<" lv. were added to the bill of "<<clients[m].name<<".";
				system("pause");
			}
			break;
		case 5:
			{	
				cout<<"\nEnter quantity not greater than :";
				cin>>quantity;
				clients[m].bill+=quantity*4;
				cout<<"\n"<<quantity*4<<" lv. were added to the bill of "<<clients[m].name<<".";
				system("pause");
			}
			break;
		case 6:
			{
				cout<<"\nEnter quantity:";
				cin>>quantity;	
				clients[m].bill+=quantity*2;
				cout<<"\n"<<quantity*2<<" lv. were added to the bill of "<<clients[m].name<<".";
				system("pause");
			}
			break;                          
		case 7:
			{
				cout<<"\nEnter quantity:";
				cin>>quantity;
				clients[m].bill+=quantity*15;
				cout<<"\n"<<quantity*15<<" lv. were added to the bill of "<<clients[m].name<<".";
				system("pause");
			}
			break;  
		}
}

void RemoveFromList(void)
{
	ShowList();
	int list;
	do{
		cout<<"\nEnter client's number to be removed from the list:";cin>>list;
		if ((list<0)||(list>=number_clients))
		{
			cout<<"\nNu such number in the list...Try again:";
			system("pause");
		}
	}
	while   ((list<0)||(list>=number_clients));
	string name=clients[list].name;
	if (list==number_clients-1)
	{
		clients[list].type="";
		clients[list].bill=0;
		clients[list].order.soup=0;
		clients[list].order.salad=0;
		clients[list].order.beefsteak=0;
		clients[list].order.pizza=0;
		clients[list].order.pancake=0;
		clients[list].order.cake=0;
		clients[list].order.soda=0;
		clients[list].order.whisky=0;
	}
	else{
		for (int i=list;i<number_clients;i++)
		{
			clients[i].name=clients[i+1].name;
			clients[i].table_number=clients[i+1].table_number;
			clients[i].type=clients[i+1].type;
			clients[i].bill=clients[i+1].bill;
			clients[i].order.soup=clients[i+1].order.soup;
			clients[i].order.salad=clients[i+1].order.salad;
			clients[i].order.beefsteak=clients[i+1].order.beefsteak;
			clients[i].order.pizza=clients[i+1].order.pizza;
			clients[i].order.pancake=clients[i+1].order.pancake;
			clients[i].order.cake=clients[i+1].order.cake;
			clients[i].order.soda=clients[i+1].order.soda; 
			clients[i].order.whisky=clients[i+1].order.whisky;
		}  
	}
	cout<<"\n"<<name<<" was successfully deleted from the list.";
	system ("pause");
	tables_booked[list]=0;  
	number_clients--;
}   

void ReadFromFile(void)
{         
	ifstream ifile("restaurant.txt");
	ifile>>number_clients;
	int table;
	for (int i=0;i<number_clients;i++)
	{
		ifile>>clients[i].name;
		ifile>>clients[i].table_number;
		ifile>>clients[i].type;
		ifile>>clients[i].bill;
		ifile>>clients[i].order.soup;
		ifile>>clients[i].order.salad;
		ifile>>clients[i].order.beefsteak;
		ifile>>clients[i].order.pizza;
		ifile>>clients[i].order.pancake;
		ifile>>clients[i].order.cake;
		ifile>>clients[i].order.soda;
		ifile>>clients[i].order.whisky;
		table=clients[i].table_number;
		tables_booked[table]=1;
	}
	ifile.close(); 
}

void WriteToFile(void)
{
	ofstream ofile("restaurant.txt");
	ofile<<number_clients<<"\n";
	for (int i=0;i<number_clients;i++)
	{
		ofile<<clients[i].name<<"\n";
		ofile<<clients[i].table_number<<"\n";
		ofile<<clients[i].type<<"\n";
		ofile<<clients[i].bill<<"\n";
		ofile<<clients[i].order.soup<<"\n";
		ofile<<clients[i].order.salad<<"\n";
		ofile<<clients[i].order.beefsteak<<"\n";
		ofile<<clients[i].order.pizza<<"\n";
		ofile<<clients[i].order.pancake<<"\n";
		ofile<<clients[i].order.cake<<"\n";
		ofile<<clients[i].order.soda<<"\n";
		ofile<<clients[i].order.whisky<<"\n";
	}
	ofile.close();  
} 
};

class One:public Table
{
private:
	void addClient(void)
	{
		Table::addClient();
		int table;
		do {
			cout<<"\nEnter table number between 1-4:";
			cin>>table;
			if(tables_booked[table]==1) 
			{
				cout<<"\nThe table is booked. Try again:";
				system("pause");
			}
			if((table<1)||(table>4)) 
			{
				cout<<"\nInvalid table number. Try again:";
				system("pause");
			}
		}
		while ((tables_booked[table]==1)||(table<1)||(table>4));
		cout<<"\n"<<clients[number_clients].name<<" was successfully added to the list.";
		system("pause");
		number_clients++;
	}
	
	virtual void addBill(void)
	{
		Table::addBill();
	}
	
};

class Two:public Table
{
private:
	void addClient(void)
	{
		Table::addClient();
		int table;
		do {
			cout<<"\nEnter table number between 5-10:";
			cin>>table;
			if(tables_booked[table]==1) 
			{
				cout<<"\nThe table is booked. Try again:";
				system("pause");
			}
			if((table<5)||(table>10))
			{
				cout<<"\nInvalid table number. Try again:";
				system("pause");
			}
		}
		while ((tables_booked[table]==1)||(table<5)||(table>10));
		cout<<"\n"<<clients[number_clients].name<<" was successfully added to the list.";
		system("pause");
		number_clients++;
	}

	virtual void addBill(void)
	{
		Table::addBill();
	}
};

class Up_to_6:public Table
{
private:
	void addClient(void)
	{
		Table::addClient();
		int table;
		do {
			cout<<"\nEnter table number between 11-17:";
                     cin>>table;
                     if(tables_booked[table]==1) 
					 {
						 cout<<"\nThe table is booked. Try again:";
						 system("pause");
					 }
					 if((table<11)||(table>17))
					 {
						 cout<<"\nInvalid table number. Try again:";
						 system("pause");
					 }
		}
		while ((tables_booked[table]==1)||(table<11)||(table>17));		
		cout<<"\n"<<clients[number_clients].name<<" was successfully added to the list.";
		system("pause");
		number_clients++;
	}

	virtual void addBill(void)
	{
		Table::addBill();
	}
};

class moreThan_6:public Table
{
private:
	void addClient(void)
	{
		Table::addClient();
		int table;
		do {
			cout<<"\nEnter table number between 18-20:";
			cin>>table;
			if(tables_booked[table]==1) 
			{
				cout<<"\nThe table is booked. Try again:";
				system("pause");
			}
			if((table<18)||(table>20)) 
			{
				cout<<"\nInvalid table number. Try again:";
				system("pause");
			}
		}
		while ((tables_booked[table]==1)||(table<18)||(table>20));		
		cout<<"\n"<<clients[number_clients].name<<" successfully added to the list.";
		system("pause");
		number_clients++;
	}

	virtual void addBill(void)
	{
		Table::addBill();
	}
};

void ProgramMenu(void)
{
	int choice;
	One aOne;
	Table *aOneTable=&aOne;
	Two aTwo;
	Table *aTwoTable=&aTwo;
	Up_to_6 aUp_to_6;
	Table *aUp_to_6Table=&aUp_to_6;
	moreThan_6 amoreThan_6;
	Table *amoreThan_6Table=&amoreThan_6;
	aOneTable->ReadFromFile();
up:
	do{
		cout<<"\n________________________________________________________________________________";
		cout<<"\n1.Reserve a table for one.";
		cout<<"\n2.Reserve a table for two.";
		cout<<"\n3.Reserve a table for up to 6 people .";
		cout<<"\n4.Reserve a table for more than 6 people.";
		cout<<"\n5.Display the list of clients.";
		cout<<"\n6.Process client's orders to their bills.";
		cout<<"\n7.Delete client from the list.";
		cout<<"\n8.Save changes and exit.";
		cout<<"\n________________________________________________________________________________";
		cout<<"\nEnter your choice:";
		cin>>choice;
		if((choice<1)||(choice>8))
		{
			cout<<"\nInvalid choice entered.Try again:";
			system("pause");
		}
	}while ((choice<1)||(choice>8));
     switch (choice)
	 {
	 case 1:{
		 aOneTable->addClient();
		 goto up;
			}
			break;
	 case 2:{
		 aTwoTable->addClient();
		 goto up;
			}
			break;
	 case 3:{
		 aUp_to_6Table->addClient();
		 goto up;
			}
			break;
	 case 4:{
		 amoreThan_6Table->addClient();
		 goto up;
			}
			break;
	 case 5:{
		 aOneTable->ShowList();
		 goto up;
			}
			break;
	 case 6:{
		 aOneTable->addBill();
		 goto up;
			}
			break;
	 case 7:{
		 aOneTable->RemoveFromList();
		 goto up;}
			break;
	 case 8:
		 aOneTable->WriteToFile();
		 break;
	 }
}   

int main(int argc, char *argv[])
{	
	cout<<"\n\t\tWelcome to the Table Booking and Bill Making Toolkit !!!"<<endl;
	ProgramMenu();
	system("PAUSE");
	return EXIT_SUCCESS;
}
class Client 
{
public:
	string name;
	Menu order;
	int table_number;
	string type;
	double bill;
	
	Client(void)
	{
		name="";
		table_number=0;
		type="";
		bill=0.0;
	}
};

This code lacks the virtual addClient table wants to use. Another note: is a table a client? If not, you shouldn't have inheritance, but perhaps composition.

Well i know Table fails the "is-a" test for inheritance, but as i said this i an entry course in C++ and the professor wont consider this, as we have a requirement to have 3 level hierarchy. If the hierarchy provided works it's fine.

Member Avatar for jencas

Either the Client ctor lacks the initialization of order or Menu lacks an appropriate ctor

Cascades of monstrous data moving... have you ever heard about operator= in C++?

clients[i] = clients[i+1];

instead of awful (quote):

clients[i].name=clients[i+1].name;
clients[i].table_number=clients[i+1].table_number;
clients[i].type=clients[i+1].type;
clients[i].bill=clients[i+1].bill;
clients[i].order.soup=clients[i+1].order.soup;
clients[i].order.salad=clients[i+1].order.salad;
clients[i].order.beefsteak=clients[i+1].order.beefsteak;
clients[i].order.pizza=clients[i+1].order.pizza;
clients[i].order.pancake=clients[i+1].order.pancake;
clients[i].order.cake=clients[i+1].order.cake;
clients[i].order.soda=clients[i+1].order.soda; 
clients[i].order.whisky=clients[i+1].order.whisky;

That famous system("pause") after prompt "Try again" ???
It seems no once input result check in the program (it's so simple)

if (!(cin >> choice)) { // not a number entered
   cout << "Not a number, try again...\n";
   cin.clear();
   cin.ignore(1000,'\n');
   continue;
}

Death sentence: there are gotos in switch statements...

I can't imagine that this program is capable to do anything...

Next time use code tag properly:
[code=cplusplus] sources

[/code]

Ok, I am pretty much sure there is plenty to be corrected and optimized. But that is not what i am asking. I just wanted to see if someone can give me a suggestion on how to implement polymorphism in this example. As you see in every 3-rd level class from the hierarchy, at the end i call this function:

virtual void addBill(void)
	{
		Table::addBill();
	}

but in this way, using the scope operator, i am not exercising any virtual functions.

Example of inheritance using virtual functions:

#include <iostream>
using namespace std;

class base {
    public:
    virtual void func(){
        cout << "First level: Base class" << endl;
    }
};

class der1 : public base {
    public:
    virtual void func(){
        cout << "Second level: Derived class" << endl;
    }
};

class der2 : public der1 {
    public:
    virtual void func(){
        cout << "Third level: Second derived class" << endl;
    }
};

int main(){
    base* all_your_base[3] = {new base, new der1, new der2};

    for(int n = 0; n < 3; n++){
        all_your_base[n]->func();
    }

    return 0;
}

Thank you Clockowl, and everyone else who took part. I managed to solve apply polymorphism on the given example. Problem solved

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.