Subclass arguments?!

I am attempting to create something like this:

class food
{
public:
void EAT(); //Whatever happens...
};

class cheese:food
{
void EAT(); //Some overloaded form of the "eat" command...
};

That all works great, but I am unsure how to pass one of those as an argument to a function at runtime. I want to be able to call the EAT() function from an instance of either object without directly specifying type (I won't know that until runtime), and without worrying about some other type accidentally being called.

Wait, what do you mean? What do you mean by call the method from an instance of either type? (I assume you wanted to make the method public in the "cheese" class as well.)

1
2
3
4
5
6
food food_instance;
cheese cheese_instance;

// calling the function
food_instance.EAT();
cheese_instance.EAT();
closed account (D80DSL3A)
I think he means to pass either a pointer or reference to one of these objects to a function and have the intended virtual eat() executed. Like this:

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
#include<iostream>
using namespace std;

class food
{
public:
	virtual void eat(void){ cout << "Eating food" << endl; }
};

class cheese: public food
{
public:
	void eat(void){ cout << "Eating cheese" << endl; }
};

void display(food* p_f)
{
	p_f->eat();// calls virtual function of type passed
}

int main(void)
{
	food f;
	cheese c;
	food* pf;

	char repeat = 'n';
	do
	{  
		char classType;
		cout << "Enter 'f' or 'c': "; cin >> classType;

		pf = classType == 'f'? &f : &c;// assign pointer to either a food or cheese object
		display(pf);	

		cout << endl << "repeat (y/n)? " << std::flush;
		cin >> repeat;

	}while( repeat=='y');

	cout << endl;
	return 0;	
}
Thanks Fun2Code!

I still don't quite understand it though...
How can a reference to a cheese variable be called through an argument for food?

Also: is there a way to directly access the object (say we add a new int variable to both classes called bitesLeft, where if you try to eat something, it lowers the bitesLeft variable of that particular object. Or would that still work?
How can a reference to a cheese variable be called through an argument for food?


By making more variables and member functions that are common between the two into public\protected variables and virtual functions for food. This way any "cheese" data types would inherit the same members and member functions that "food" data types have.
closed account (D80DSL3A)
You're welcome.
As Computergeek01 points out you can add more data and function members to the base class then access these in either the base or derived classes through a pointer to the base class.

You can't use a pointer to the base class to directly access data or function members which are not inherited from the base class, but you can still manipulate the non-inherited members through virtual versions of the base class functions.

I am avoiding work on my own project today, so I put together another example here to show that.

Suppose that the food class is not meant to model any particular food. It describes only things common to all foods. It seems appropriate to make food an abstract class:

1
2
3
4
5
6
7
// no particular food type implied
class food// abstract class
{
public:
	int bitesLeft;// a property of all foods
	virtual void eat(void) = 0;// something you must do with food.
};


Now a class for a particular food item. Burgers!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// burger is a type of food
class burger: public food// MUST implement the eat()
{
public:
	void eat(void)
	{
		if( bitesLeft > 0 )
		{
			cout << "Taking a bite of burger.";
			bitesLeft--;
			cout << " bitesLeft = " << bitesLeft;
			if( bitesLeft == 0 )
				cout << " The burger is now eaten!";
		}
	}
};


Now for something which is not food, but goes with food sometimes. An unrelated class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class soda// goes with the burger in a meal
{
public:
	int sipsLeft;
	void drink(void)
	{		
		if( sipsLeft > 0 )
		{
			cout << " and a sip of soda.";
			sipsLeft--;
			cout << " sipsLeft = " << sipsLeft;
			if( sipsLeft == 0 )
				cout << endl << " Soda is now empty";
		}
		else
			cout << endl << "Damn! The soda is empty";
	}
};


Next, let's make a meal from a burger and a soda
1
2
3
4
5
6
7
8
9
10
11
12
// meal inherits a burger then adds a soda
class meal: public burger// food is now an indirect base class of meal
{
public:
	soda mySoda;
	void eat(void)// meal version of the eat()
	{
		burger::eat();// calling burger version of the eat()
		if( bitesLeft%3 == 0 )// sip soda every 3rd bite
			mySoda.drink();
	}
};


Lets eat the meal using a food*, to show we can manipulate an object (soda) which is unrelated to food through the food*:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(void)
{
	meal m;
	m.bitesLeft = 12;
	m.mySoda.sipsLeft = 3;

	food* pf = &m;

	while( pf->bitesLeft )// eat until the food is gone			
		pf->eat();
	
	cout << endl;
	return 0;	
}

These are some really cool tools we can work with here!!
Topic archived. No new replies allowed.