473,705 Members | 2,417 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

A (Simple) Polymorphism Query

Hi Everyone,

Please take a look at the following (simple and fun) program:

////////////////////////////////////////////////////////////////////////////
/////////////
// Monster Munch, example program

#include <list>

class CFood
{
public:
CFood() {}
virtual ~CFood() {}
};

class CFoodCookie : public CFood
{
public:
CFoodCookie() {}
virtual ~CFoodCookie() {}
};

class CFoodHorse : public CFood
{
public:
CFoodHorse() {}
virtual ~CFoodHorse() {}
};

class CMonster
{
public:
CMonster() {}
~CMonster() {}

// The (greedy) monster may eat several things
void Eat(CFood* pSnack) {delete pSnack; printf("\nI ate summink, but I know
not what.");}
void Eat(CFoodCookie * pSnack) {delete pSnack; printf("\nYummy ! A
cookie!");}
void Eat(CFoodHorse* pSnack) {delete pSnack; printf("\nI was so hungry I
ate a horse!");}
};

class CPantry
{
public:
CPantry() {}
~CPantry() {}

void AddFood(CFood* pFood)
{
// Add the food to our supplies
m_Stock.push_ba ck(pFood);
}

void Feed(CMonster& Monster)
{
while (m_Stock.size() )
{
// Get the food...
CFood* pFood = m_Stock.front() ;
m_Stock.pop_fro nt();

// Feed the monster
Monster.Eat(pFo od);
}
}

private:
std::list<CFood *> m_Stock;
};

int _tmain(int argc, _TCHAR* argv[])
{
CPantry ThePantry;

// Let's see what we have:
// Two cookies...
ThePantry.AddFo od(new CFoodCookie());
ThePantry.AddFo od(new CFoodCookie());
// Goodness knows what this is...
ThePantry.AddFo od(new CFood());
// And this, apparently...
ThePantry.AddFo od(new CFoodHorse());

// Feed the guest...
CMonster ScaryDude;
ThePantry.Feed( ScaryDude);

getchar();

return 0;
}
////////////////////////////////////////////////////////////////////

I may be overlooking a very simple trick indeed, but my question is this:
how do I have the monster know what he (or she, who knows?) is eating? There
are a couple of factors that I wish to preserve in the solution:
1. The monster must have the overloaded Eat members as I intend to implement
similar classes that will eat the same and different foods in different
manners (with manners, perhaps? :-) ).
2. The pantry must be the source of food and must store food in a generic
manner.
3. I want users to implement new CFood derived classes as simply as
possible.

I could, for example, have a virtual Feed(CMonster&) method in all CFood
derived classes that executes Monster.Eat(thi s). However, this would impact
factor 3 in that all new CFood-derived classes would need to add this
method - if implemented in the CFood base class only, the monster would only
eat generic food.

What would be your suggestions, folks? Is there a simple, or non-simple
polymorphic step I am missing? Would templates be an answer somewhere?

Many, many thanks!
Lucy x
Jul 19 '05 #1
3 3692
"Patchwork" <ID***********@ IDontLike.Spam> wrote...
Please take a look at the following (simple and fun) program:

//////////////////////////////////////////////////////////////////////////// /////////////
// Monster Munch, example program

#include <list>

class CFood
{
public:
CFood() {}
virtual ~CFood() {}
};

class CFoodCookie : public CFood
{
public:
CFoodCookie() {}
virtual ~CFoodCookie() {}
};

class CFoodHorse : public CFood
{
public:
CFoodHorse() {}
virtual ~CFoodHorse() {}
};

class CMonster
{
public:
CMonster() {}
~CMonster() {}

// The (greedy) monster may eat several things
void Eat(CFood* pSnack) {delete pSnack; printf("\nI ate summink, but I know not what.");}
void Eat(CFoodCookie * pSnack) {delete pSnack; printf("\nYummy ! A
cookie!");}
void Eat(CFoodHorse* pSnack) {delete pSnack; printf("\nI was so hungry I
ate a horse!");}
};

class CPantry
{
public:
CPantry() {}
~CPantry() {}

void AddFood(CFood* pFood)
{
// Add the food to our supplies
m_Stock.push_ba ck(pFood);
}

void Feed(CMonster& Monster)
{
while (m_Stock.size() )
{
// Get the food...
CFood* pFood = m_Stock.front() ;
m_Stock.pop_fro nt();

// Feed the monster
Monster.Eat(pFo od);
}
}

private:
std::list<CFood *> m_Stock;
};

int _tmain(int argc, _TCHAR* argv[])
This is not C++. In C++ the entry point should be called
'main' and have very particular parameters.
{
CPantry ThePantry;

// Let's see what we have:
// Two cookies...
ThePantry.AddFo od(new CFoodCookie());
ThePantry.AddFo od(new CFoodCookie());
// Goodness knows what this is...
ThePantry.AddFo od(new CFood());
// And this, apparently...
ThePantry.AddFo od(new CFoodHorse());

// Feed the guest...
CMonster ScaryDude;
ThePantry.Feed( ScaryDude);

getchar();

return 0;
}
////////////////////////////////////////////////////////////////////

I may be overlooking a very simple trick indeed, but my question is this:
how do I have the monster know what he (or she, who knows?) is eating?
Unless you somehow perform run-time type resolution (like dynamic_cast,
for example), and keep passing 'CFood*' to the overloaded member of
the CMonster class, CMonster::Eat(C Food*) _shall__always_ be chosen.

Now, there is a bigger problem here. Your CMonster will still _have_to_
know all the different foods there possibly can be in order to behave
correctly. That's no polymorphism.
There
are a couple of factors that I wish to preserve in the solution:
1. The monster must have the overloaded Eat members as I intend to implement similar classes that will eat the same and different foods in different
manners (with manners, perhaps? :-) ).
That means you will have to limit your monster to some _categories_ of
food, anyway. So, why don't you place that category table (or list, or
enumeration) into the CFood base class and let the monster behave
differently based on the category the food returns?
2. The pantry must be the source of food and must store food in a generic
manner.
3. I want users to implement new CFood derived classes as simply as
possible.

I could, for example, have a virtual Feed(CMonster&) method in all CFood
derived classes that executes Monster.Eat(thi s). However, this would impact factor 3 in that all new CFood-derived classes would need to add this
method - if implemented in the CFood base class only, the monster would only eat generic food.
In polymorphism, the only way to do it is to let CFood descendants
provide the distinguishing functionality. Otherwise, it's not the
polymorphism we know.
What would be your suggestions, folks? Is there a simple, or non-simple
polymorphic step I am missing? Would templates be an answer somewhere?


You're missing the whole point of polymorphism, I am afraid.

Victor
Jul 19 '05 #2
Hi Victor,

Thanks for your response...

----- Original Message -----
From: "Victor Bazarov" <v.********@com Acast.net>
Newsgroups: comp.lang.c++
Sent: Sunday, November 16, 2003 4:27 AM
Subject: Re: A (Simple) Polymorphism Query

"Patchwork" wrote...
Please take a look at the following (simple and fun) program:

////////////////////////////////////////////////////////////////////////////
/////////////
// Monster Munch, example program

#include <list>

class CFood
{
public:
CFood() {}
virtual ~CFood() {}
};

class CFoodCookie : public CFood
{
public:
CFoodCookie() {}
virtual ~CFoodCookie() {}
};

class CFoodHorse : public CFood
{
public:
CFoodHorse() {}
virtual ~CFoodHorse() {}
};

class CMonster
{
public:
CMonster() {}
~CMonster() {}

// The (greedy) monster may eat several things
void Eat(CFood* pSnack) {delete pSnack; printf("\nI ate summink, but I

know
not what.");}
void Eat(CFoodCookie * pSnack) {delete pSnack; printf("\nYummy ! A
cookie!");}
void Eat(CFoodHorse* pSnack) {delete pSnack; printf("\nI was so hungry I ate a horse!");}
};

class CPantry
{
public:
CPantry() {}
~CPantry() {}

void AddFood(CFood* pFood)
{
// Add the food to our supplies
m_Stock.push_ba ck(pFood);
}

void Feed(CMonster& Monster)
{
while (m_Stock.size() )
{
// Get the food...
CFood* pFood = m_Stock.front() ;
m_Stock.pop_fro nt();

// Feed the monster
Monster.Eat(pFo od);
}
}

private:
std::list<CFood *> m_Stock;
};

int _tmain(int argc, _TCHAR* argv[])


This is not C++. In C++ the entry point should be called
'main' and have very particular parameters.


Point taken, I overlooked this added by my compiler in a dash to create the
demonstration program.
{
CPantry ThePantry;

// Let's see what we have:
// Two cookies...
ThePantry.AddFo od(new CFoodCookie());
ThePantry.AddFo od(new CFoodCookie());
// Goodness knows what this is...
ThePantry.AddFo od(new CFood());
// And this, apparently...
ThePantry.AddFo od(new CFoodHorse());

// Feed the guest...
CMonster ScaryDude;
ThePantry.Feed( ScaryDude);

getchar();

return 0;
}
////////////////////////////////////////////////////////////////////

I may be overlooking a very simple trick indeed, but my question is this: how do I have the monster know what he (or she, who knows?) is eating?


Unless you somehow perform run-time type resolution (like dynamic_cast,
for example), and keep passing 'CFood*' to the overloaded member of
the CMonster class, CMonster::Eat(C Food*) _shall__always_ be chosen.


Again, thanks for taking the time to look over the code. I do see that this
is my problem but I was hoping there would be a simple and convenient way to
pass the desired class type without implementing this in CFood-derived
classes.
Now, there is a bigger problem here. Your CMonster will still _have_to_
know all the different foods there possibly can be in order to behave
correctly. That's no polymorphism.
Hmm. Again, I see your point. My subject heading is the erroneous factor
here. I do desire that the monster behaves this way with a pre-determined
list of foods specifically handled. Polymorphic behaviour, in its true
sense, is expected of the CFood classes within the CPantry class and
elsewhere. Consequently, it is only the CMonster class that I wish to
implement in this novel manner by reacting differently to different foods.
The 'handler' for the generic food type is there to allow the monster to eat
any type of food indiscriminatel y if required.
There
are a couple of factors that I wish to preserve in the solution:
1. The monster must have the overloaded Eat members as I intend to

implement
similar classes that will eat the same and different foods in different
manners (with manners, perhaps? :-) ).


That means you will have to limit your monster to some _categories_ of
food, anyway. So, why don't you place that category table (or list, or
enumeration) into the CFood base class and let the monster behave
differently based on the category the food returns?


Indeed, the moster's CFood type handling isn't an overisight, as mentioned
above. The bigger picture is that we may have a CLifeform class with
subclasses that override handlers only for the foodtypes they are interested
in eating. Do you think categories via enumerated types, etc would be the
ideal solution? I was wanting to avoid implementing type checks/cases in the
CMonster class by having certain foods naturally handled in their
corresponding method overrides.
2. The pantry must be the source of food and must store food in a generic manner.
3. I want users to implement new CFood derived classes as simply as
possible.

I could, for example, have a virtual Feed(CMonster&) method in all CFood
derived classes that executes Monster.Eat(thi s). However, this would

impact
factor 3 in that all new CFood-derived classes would need to add this
method - if implemented in the CFood base class only, the monster would

only
eat generic food.


In polymorphism, the only way to do it is to let CFood descendants
provide the distinguishing functionality. Otherwise, it's not the
polymorphism we know.


Yes, again, I make no excuses for the mistitled e-mail but could you think
of any further tricks that may help me achieve what I hope for?
What would be your suggestions, folks? Is there a simple, or non-simple
polymorphic step I am missing? Would templates be an answer somewhere?


You're missing the whole point of polymorphism, I am afraid.


Well, let's say I suffered an aberrant thought when naming the message...:-)

Perhaps I will rethink my overall design (surely your recommendation? :-) )
but any further suggestions would be most appreciated. I don't really know
of any newsgroups that would be interested in discussing models, etc in C++
that would be interested in making some suggestions for another design. Any
help from anyone here in achieving what I desire would be _most_ appreciated
:-)

To reiterate the requirements:
1) There is a class type CFood which will have more subclasses added in the
future. Each foodtype will have its own properties, etc making good use of
polymorphism where appropriate (honest).
2) There is a class CPantry which will store a dynamic quantity of CFood
based classes. The specific CFood-derived class type need not be known.
3) There is a class CLifeform that will have subclasses such as CMonster or
CHumanoid. Each CLifeform-based class may process or eat CFood-based objects
differently. A default 'handler' may be desirable just to mention that the
lifeform is not interest in the food type.
4) Other classes (not CLifeform-drived) may also 'handle' CFood objects.

If the above model is not appropriate...w hat could be changed? Or what
could be used in its place?

Perhaps it is more appropriate to post this as a new question...?
Victor


Thanks, Victor
Lucy x
Jul 19 '05 #3
"Patchwork" <ID***********@ IDontLike.Spam> wrote...
----- Original Message -----
From: "Victor Bazarov" <v.********@com Acast.net>
Newsgroups: comp.lang.c++
Sent: Sunday, November 16, 2003 4:27 AM
Subject: Re: A (Simple) Polymorphism Query

"Patchwork" wrote...
Please take a look at the following (simple and fun) program: [...]
Now, there is a bigger problem here. Your CMonster will still _have_to_
know all the different foods there possibly can be in order to behave
correctly. That's no polymorphism.
Hmm. Again, I see your point. My subject heading is the erroneous factor
here. I do desire that the monster behaves this way with a pre-determined
list of foods specifically handled. Polymorphic behaviour, in its true
sense, is expected of the CFood classes within the CPantry class and
elsewhere. Consequently, it is only the CMonster class that I wish to
implement in this novel manner by reacting differently to different foods.
The 'handler' for the generic food type is there to allow the monster to

eat any type of food indiscriminatel y if required.
There
are a couple of factors that I wish to preserve in the solution:
1. The monster must have the overloaded Eat members as I intend to implement
similar classes that will eat the same and different foods in different manners (with manners, perhaps? :-) ).


That means you will have to limit your monster to some _categories_ of
food, anyway. So, why don't you place that category table (or list, or
enumeration) into the CFood base class and let the monster behave
differently based on the category the food returns?


Indeed, the moster's CFood type handling isn't an overisight, as mentioned
above. The bigger picture is that we may have a CLifeform class with
subclasses that override handlers only for the foodtypes they are

interested in eating. Do you think categories via enumerated types, etc would be the
ideal solution? I was wanting to avoid implementing type checks/cases in the CMonster class by having certain foods naturally handled in their
corresponding method overrides.
Alright, given these new conditions, I don't think that enumerators
would be ideal. The _ideal_ would be to teach each life form to
recognise the food they can eat (based on some specific characteristics
of the food, like hallucinogen-ness) and store [a pointer to] a sample
in their "set of acceptable foods". The whole point of it is that you
(or your life forms) can never tell what foods they will encounter on
their path to oblivion, especially considering that foods and creatures
are not related types and can be created independently.

So, let's re-visit categories now. What you need to give your CFood
class is a way to express itself: soft, chunky, needs cooking, stinks,
liquid, fatty, etc., and also give your CLifeform a mechanism which
will calculate acceptability of a particular food based on its factors.
I imagine that it is possible that your monster would say "I don't know
what I just ate, but it tasted like horse".
[...]
Perhaps I will rethink my overall design (surely your recommendation? :-) ) but any further suggestions would be most appreciated. I don't really know
of any newsgroups that would be interested in discussing models, etc in C++ that would be interested in making some suggestions for another design. Any help from anyone here in achieving what I desire would be _most_ appreciated :-)
Two suggestions: James Coplien's "Advanced C++" (1991) and comp.object.

To reiterate the requirements:
1) There is a class type CFood which will have more subclasses added in the future. Each foodtype will have its own properties, etc making good use of
polymorphism where appropriate (honest).
Sounds good. Among the properties you could add a name, which will
be set by a first creature ever trying the food (unless the food has
already been stored in a box with a known name). Other creatures
can then ask the food what its name is and store the name (not some
'sample') in the set of foods it likes.
2) There is a class CPantry which will store a dynamic quantity of CFood
based classes. The specific CFood-derived class type need not be known.
Sure. Seems OK. Unless the food needs to be refridgirated to be
OK (or does your pantry have a fridge in it?)
3) There is a class CLifeform that will have subclasses such as CMonster or CHumanoid. Each CLifeform-based class may process or eat CFood-based objects differently. A default 'handler' may be desirable just to mention that the
lifeform is not interest in the food type.
Well, see above. I think that more sophisticated mechanism for the
life forms to distinguish between foods is needed.
4) Other classes (not CLifeform-drived) may also 'handle' CFood objects.

If the above model is not appropriate...w hat could be changed? Or what
could be used in its place?
It's appropriate. It's just too generic. You might want to begin
stating the details, for example, how would "other classes" "handle"
food? Spoil it? Heat it? A food's properties should probably
change based on that. Have you thought of what properties and how
are going to change?
Perhaps it is more appropriate to post this as a new question...?


Nah, just keep digging, I am fairly certain you're on the right track.

Good luck, and keep asking those questions!

Victor
Jul 19 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

18
12589
by: Ken | last post by:
Hi. Can anyone refer me to any articles about the compatibility between c++ polymorphism and real-time programming? I'm currently on a real-time c++ project, and we're having a discussion about whether we should allow polymorphism. Our system is not embedded and does not need to be as real-time as, say, a pacemaker. But it does involve updating displays based on radar input. So a need for something close to real-time is desired...
11
5095
by: richard pickworth | last post by:
Can anyone explain polymorphism?(very simply). thanks richard
12
7051
by: Steve Jorgensen | last post by:
The classing Visual Basic and VBA support for polymorphism, let's face it, is a bit on the weak side, and built-in support for inheritance is non-existent. This little essay is about some patterns I've ended up using successfully for certain kinds of inheritance and polymorphism, and some that have not worked out so well. Let's start with obvious things that turn out not to work well: 1. Use interface classes and "Implements" for...
4
7391
by: LP | last post by:
Hi, I understand the concept/definition of polymorphism. But what does the term "runtime polymorphism" mean? I was asked to define it during a technical interview. I gave a guy vanilla definition of polymorphism, but he insisted on runtime. Did I miss a new buzzword while I was sick with the flu last week or something like that?
4
2052
by: Mike | last post by:
It looks to me that in using that in creating generic IEnumerables, you lose polymorphic capabilities. Consider this pseudo code: abstract class BaseClass; class DerivedClassSpecialFunction1 : BaseClass class DerivedClassSpecialFunction2 : BaseClass
1
1776
by: relient | last post by:
Hi, I just started the chapter on "Inheritance" and I'm a bit confused so I have three questions: first, here's the code: using System; using System.Collections.Generic; using System.Text; namespace ConsoleProject1 { public class Base
2
3387
by: sarathy | last post by:
Hi all, I need a small clarification reg. Templates and Polymorphism. I believe templates is really a good feature, which can be used to implement generic functions and classes. But i doubt whether it should not be used in certain cases. Consider the case when all the params to a template function/class are similar. My questions is that whatever can be acheived by a template in such a case, can be acheived by runtime polymorphism....
11
2972
by: chsalvia | last post by:
I've been programming in C++ for a little over 2 years, and I still find myself wondering when I should use polymorphism. Some people claim that polymorphism is such an integral part of C++, that anybody who doesn't use it might as well just program in plain C. I totally disagree with this, because I think C++ has a lot of great features apart from polymorphism, such as the ability to organize code into classes, code reuse through...
17
3875
by: Bart Friederichs | last post by:
Hello, I created the following inheritance: class Parent { public: void foo(int i); }; class Child : public Parent {
0
8689
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9273
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9030
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7893
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5933
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4439
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4703
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3137
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2081
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.