Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > inheritance doesn't works as expected

Reply
Thread Tools

inheritance doesn't works as expected

 
 
Tony Johansson
Guest
Posts: n/a
 
      08-19-2005
Hello Experts!

I have some class definition and a main below.
This is a strange problem.
When cout is executing in the for loop below locating in main I get this
print out on the screen
Bird eats Bird food
Cat eats Birds
for(int i = 0; i<sizeof p/sizeof *p; i++)
cout << p[i]->type() << " eats " << p[i]->eats()->foodType() << endl;
The strange thing is that it doesn't matter what return type I have on the
eats method I always get
the same answer which is the same as above.

I mean these two gives the same output for class Bird when foodType() is
called in the for loop
BirdFood* eats()
PetFood* eats()

and these two gives the same output for class Cat when foodType() is called
in the for loop
CatFood* eats()
PetFood* eats()

Just to try to understand this I removed the virtual for this foodType
method in class PetFood.
Now I always get the same output which is
Bird eats Pet food
Cat eats Pet food.
it doesn't matter if I have
CatFood* eats()
or
PetFood* eats()
In class Cat.

I mean if I don't use virtual I will be using the static type and not the
dynamic type.
This would mean that if I return CatFood* eats()
I would be calling foodType in class CatFood and not in class PetFood.


//Class definitions
#include <iostream>
#include <string>
using namespace std;

class PetFood
{
public:
string foodType() const
{ return "Pet food"; }
};

class Pet
{
public:
virtual string type() const = 0;
virtual PetFood* eats() = 0;
};

class Bird : public Pet
{
public:
string type() const
{ return "Bird"; }

class BirdFood : public PetFood
{
public:
string foodType() const
{ return "Bird food"; }
};

PetFood* eats()
{ return &bf; }

private:
BirdFood bf;
};

class Cat : public Pet
{
public:
string type() const
{ return "Cat"; }

class CatFood : public PetFood
{
public:
string foodType() const
{ return "Birds"; }
};

CatFood* eats()
{ return &cf; }

private:
CatFood cf;
};

#include <iostream>
#include "pet.h"
using namespace std;
int main()
{
Bird b;
Cat c;
Pet* p[] = {&b, &c};

for(int i = 0; i<sizeof p/sizeof *p; i++)
cout << p[i]->type() << " eats " << p[i]->eats()->foodType() << endl;
return 0;
}

Many thanks

//Tony


 
Reply With Quote
 
 
 
 
Josh Mcfarlane
Guest
Posts: n/a
 
      08-19-2005
Tony Johansson wrote:
[snip]

Judging from the number of questions you're posting per day on this
newsgroup, you may want to consider another method of learning. If
you're taking a class, it might be time to talk to your professor about
the things you're asking about on the list. If you're using a book, you
may want to consider getting a new one.

Not to be mean, but these questions all seem like they'd come off a
homework assignment from someone's programming course. Always a few
theory questions and then an problem.

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      08-19-2005
Tony Johansson wrote:
> I have some class definition and a main below.
> This is a strange problem.


There is nothing strange about it. And there is no problem. The program
behaves _absolutely_ according to language rules.

> When cout is executing in the for loop below locating in main I get this
> print out on the screen
> Bird eats Bird food
> Cat eats Birds
> for(int i = 0; i<sizeof p/sizeof *p; i++)
> cout << p[i]->type() << " eats " << p[i]->eats()->foodType() << endl;
> The strange thing is that it doesn't matter what return type I have on the
> eats method I always get
> the same answer which is the same as above.
>
> I mean these two gives the same output for class Bird when foodType() is
> called in the for loop
> BirdFood* eats()
> PetFood* eats()


Since 'BirdFood' is a derived class of 'PetFood', a pointer to it is
"covariant" to the pointer its base.

> and these two gives the same output for class Cat when foodType() is called
> in the for loop
> CatFood* eats()
> PetFood* eats()


Same thing.

In both cases, 'eats' in the derived class is the overrider for the base
class' function 'eats'.

The return value type comes into play if you call your function through
a pointer or a reference of either the base class or the derived class.
That's the main reason to have covariant return value types.

> Just to try to understand this I removed the virtual for this foodType
> method in class PetFood.


So, you disabled polymorphism. Now, 'BirdFood' or 'CatFood' are not
polymorphic types any longer. When 'eats' returns a pointer to 'PetFood',
that's how the object is treated. A call to 'foodType' always resolves
into 'PetFood::foodType'.

If you keep 'virtual', then the call will be resolved _polymorphically_,
according to the type with which the object (pointed to by 'PetFood*')
was _constructed_. In case of 'BirdFood' 'BirdFood::foodType' is called,
in case of 'CatFood' 'CatFood::foodType'.

> Now I always get the same output which is
> Bird eats Pet food
> Cat eats Pet food.
> it doesn't matter if I have
> CatFood* eats()
> or
> PetFood* eats()
> In class Cat.


Yes, it doesn't matter. The returned pointer is of type 'PetFood*',
since you call it through a _pointer_to_Pet_. Had you called 'eats'
through a pointer to 'Cat', you'd get 'CatFood*' (if 'eats' had been
declared to have covariant return value types).

> I mean if I don't use virtual I will be using the static type and not the
> dynamic type.


Right.

> This would mean that if I return CatFood* eats()
> I would be calling foodType in class CatFood and not in class PetFood.


No. The return value type of Pet::eats is not CatFood*, it's PetFood*.
You would only be calling 'CatFood::foodType' _iff_ the function is
virtual.

> [...]


V
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Multilevel class inheritance not working as expected Jörg Battermann Ruby 2 02-08-2008 11:30 PM
Inheritance not working as expected KJF Ruby 4 04-01-2007 06:17 PM
When I turn on my PC, it works, works, works. Problem! Fogar Computer Information 1 01-17-2006 12:57 AM
FormsAuthentication works as expected on a couple older websites, but not the same on a new website... Dean R. Henderson ASP .Net 1 04-25-2005 08:26 PM
After rebooting my PC works, works, works! Antivirus problem? Adriano Computer Information 1 12-15-2003 05:30 AM



Advertisments