forward declaration / undefined classes -> errors w/ Pizza Factory

I think the problem I'm having is that C++ cannot work with class instances without initializing them in a more explicit way than I am doing, but I'm not sure how to solve this... maybe there's an easy solution but it isn't obvious to me. does someone see another approach to this? or a way to make this forward declaration work?

two main errors I'm getting are:
1) forward declaration of struct 'Topping' (at the 1st line - class Topping)
2) invalid use of undefined type struct 'Topping' (at the 2nd line -class Sausage : public Topping)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#include <string>
#include <list>
#include <iostream>
using namespace std;

// def_topping( Sausage, 2, S )
// def_topping( Small, 2, s )

class Topping;
class Sausage : public Topping
	{
	public:
		string name() {return "Sausage";}
		int cost(){return 200;}
		char c(){return 'S';}
	};
class ExtraCheese : public Topping
	{
	public:
		string name() {return "Extra Cheese";}
		int cost(){return 185;}
		char c(){return 'E';}
	};
class Hamburger : public Topping
	{
	public:
		string name() {return "Hamburger";}
		int cost(){return 200;}
		char c(){return 'H';}
	};
class Pepperoni : public Topping
	{
	public:
		string name() {return "Pepperoni";}
		int cost(){return 200;}
		char c(){return 'P';}
	};
class CanadianBacon : public Topping
	{
	public:
		string name() {return "Canadian Bacon";}
		int cost(){return 275;}
		char c(){return 'C';}
	};
class Onions : public Topping
	{
	public:
		string name() {return "Onions";}
		int cost(){return 150;}
		char c(){return 'O';}
	};
class Beer : public Topping
	{
	public:
		string name() {return "Beer";}
		int cost(){return 325;}
		char c(){return 'B';}
	};
class Small : public Topping
	{
	public:
		string name() {return "Small";}
		int cost(){return 800;}
		char c(){return 's';}
	};
class Medium : public Topping
	{
	public:
		string name() {return "Medium";}
		int cost(){return 1000;}
		char c(){return 'm';}
	};
class Large : public Topping
	{
	public:
		string name() {return "Large";}
		int cost(){return 1200;}
		char c(){return 'l';}
	};
class Family : public Topping
	{
	public:
		string name() {return "Family";}
		int cost(){return 1600;}
		char c(){return 'f';}
	};

class Topping
	{
	public:
		static Topping * new_topping(char c)
		{
			switch(c)
			{
				case 'S':
					return new Sausage;
				case 'E':
					return new ExtraCheese;
				case 'P':
					return new Pepperoni;
				case 'H':
					return new Hamburger;
				case 'C':
					return new CanadianBacon;
				case 'O':
					return new Onions;
				case 'B':
					return new Beer;
				case 's':
					return new Small;
				case 'm':
					return new Medium;
				case 'l':
					return new Large;
				case 'f':
					return new Family;
					
			}
		}
		
		virtual string name();
		virtual int cost();
		virtual char c();
	};

class Pizza				// singleton pattern (manages THE pizza)
	{
	public:
		static void createPizza();
		static void printReceipt();
		static void createPizza(char size, string toppings);
		static void addToppings(string toppings);
		static void removeToppings(string toppings);
		static void changeSize(char size);

		static list<Topping*> pizza;
	};

list<Topping*> Pizza::pizza = list<Topping*>(); // initializes to an empty list

int main(){
	
	std::cout << "Making empty pizza...\n";
	Pizza::createPizza();
	Pizza::printReceipt();			// includes printing the cost
	
	std::cout << "Making large, spc pizza\n";
	Pizza::createPizza('L', "spc");
	Pizza::printReceipt();			// includes printing the cost
	
	Pizza::addToppings("of");
	Pizza::printReceipt();			// includes printing the cost
	
	Pizza::removeToppings("");			
	Pizza::printReceipt();			// includes printing the cost
	
	Pizza::changeSize('L');
	Pizza::printReceipt();			// includes printing the cost
	
	Pizza::createPizza();
	Pizza::printReceipt();			// test to make sure this pizza prints empty
	
	
    cout << "Hello" << endl;
	return 0;
}

void Pizza::createPizza()
{
	for(list<Topping*>::iterator i = Pizza::pizza.being(); i != Pizza::pizza.end(); i++)
	{
		delete(i);
	}
	Pizza::pizza.clear;
	
}

void Pizza::createPizza(char size, string toppings)
{
	for (list<Topping*>::iterator i = Pizza::pizza.begin(); i!= Pizza::pizza.end(); i++)
	{ delete(i); }
	Pizza::pizza.clear();	// resets the pizza everytime createPizza is called
	
	Pizza::pizza.push(Topping::new_topping(size));
	
	Pizza::addToppings(toppings);
}
void Pizza::addToppings(string toppings)
{
	for(string::iterator t = toppings.begin(); t != toppings.end(); t++)
	{
		Pizza::pizza.push(Topping::new_topping(*t);
	}       
}
						 
void Pizza::changeSize(char size)
{
list<Topping*>::iterator i;
i = Pizza::pizza.begin();
delete(i);
Pizza::pizza.replace(i, Topping::new_topping(size));
}
void Pizza::removeToppings(string toppings)
{
	//  validate input
	for (string::iterator r = toppings.begin(); r!= toppings.end(); r++) 
	{
		for (list<Topping*>::iterator i = Pizza::pizza.begin(); i!= Pizza::pizza.end(); i++)
		{
				if ( i->c(); == *r)
				{
					i=Pizza::pizza.erase(i);  // increments iterator
					i--;   //  decerement interator to counteract incrementation 
				}
		}
	}
} // removeToppings(..)
				
void Pizza::printReceipt()
{
	int total = 0;
	for (list<Topping*>::iterator i = Pizza::pizza.begin(); i!= Pizza::pizza.end(); i++)
	{
		cout << i->name();
		total += i->cost();
	}
}
						  
						  
		
Forward declaration is only enough when all you have is pointers or references to objects of that class. As soon as you start to call functions, inherit from or in other ways using the class you need to have defined the class before that.

In your code you must put the class definition of Topping before all the other classes that use it. If you do that you will get a problem because the new_topping function is using other classes that is not yet defined. What you can do is to only have the function declaration inside the class definition and put the function definition outside the class definition after the other classes.

In bigger programs you often separate code into different files and have class definitions and function declarations in a header file and all the function definitions in a source file. When getting used to this it becomes easier and you don't have to think much about what order to define things in as you have to do if you put everything in one file like you do.
Topic archived. No new replies allowed.