• Advertisement
Sign in to follow this  

what happends when... (polymorphism question)

This topic is 4834 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi, lets say we had these 3 classes:
class Parent
{
  public:
  
  ...
   void Hello(Son *p);
   void Hello(Daughter *p);
   void Hello(Parent   *p);
};

class Son : public Parent
{
  ...
};

class Daughter : public Parent
{
  ..
};


now, what happends if we do this:
Parent Dad,Mom;
dad.Hello(&Mom);
what happends here? which function is called?

Share this post


Link to post
Share on other sites
Advertisement
Did I miss something? Why wouldn't Parent::Hello(Parent*) be called?

Also you would have to declare Son and Daughter before referencing them in Parent, like so:

class Son;
class Daughter;

class Parent
{
//...
};

class Son : public Parent
{
//...
};

class Daughter : public Parent
{
//...
};




Share this post


Link to post
Share on other sites
Hello(Son *s). you're simply overloading the function Hello with different class types as arguments. you could even do :

Parent* a = new Parent();
Parent* b = new Parent();
a->Hello((Son*)b); // calls Hello(Son* p);

// or
Parent* a = new Parent();
Son* b = new Son();

b->Hello((Daughter*)a); // probably should use static_cast

Share this post


Link to post
Share on other sites
hi stormrunner,

heh, its been awhile since ive thought about this stuff... but i don't understand your first example. how is it possible for a parent to turn into a child pointer? i thought only a child could be used as a parent, and not vice-versa. i mean, what if Son has members which Parent doesn't? if you cast the parent to a son, i just dont see how this is possible because then the function could mess with Son:: members when the pointer really belongs to a parent, who doesnt have those members. i just dont see how that works out... i mean, my only guess is that those members are only temporary and when the function returns it loses any child members. heh, didnt even know about that.. i guess its about time i learned about the casting of pointers in situations like this, i've been putting it off for awhile because i haven't needed it [smile]

thanks for any help.



[Edited by - graveyard filla on October 25, 2004 12:23:07 AM]

Share this post


Link to post
Share on other sites
i gotta run, but heres my hacked demo. i tested it with dev just to be sure.

#include <iostream>
class b;
class c;
class a
{
public:
void A(a* _a)
{
std::cout << "a* called" << std::endl;
}
void A(b* _a)
{
std::cout << "b* called" << std::endl;
}
void A(c* _a)
{
std::cout << "c* called" << std::endl;
}
void printA(void)
{
std::cout << "print from a" << std::endl;
}
};
class b : public a
{
/* just inherits everything from a */
};
class c : public a
{
public:
void access(c* _a)
{
_a->print();
}
void print(void)
{
std::cout << "i can print" << std::endl;
}
};
int main()
{
a* _A = new a();
a* _B = new a();
_A->A(_B); // calls (b*)
_A->A((c*)_B); // cast to a child (c*)
c* _C = new c(); // a new child : a
_C->A((b*)_A); // cast to a child - calls (b*)
_C->access((c*)_A); // cast to a child - calls (c*)
// calls class [c] specific function
_A->A((a*)_C); // cast to a parent - calls (a*)
// uses class [a] specific function
int a;
std::cin >> a;
return(0);
}



Share this post


Link to post
Share on other sites
Graveyard,

I fail to see where your confusion lies. You're deriving a child class from a parent class, then calling a function on the child class. That's pretty basic. There's no polymorphism here.

The hello function will always resolve to the highest level of the parameters.

so...

Son son;
Parent dad;
dad.Hello(&son);

Will just call the hello function on the Parent object which took Son* as a parameter.

ie.
Parent::Hello( Son* p );

Nothing you have here is declared virtual, so it is impossible for you to get any polymorphism out of this.

Polymorphism is used to call the function of a derived class when you have a pointer to the base class...

Example:

class Parent
{
public:
virtual void HellO();
};

class Child : public Parent
{
public:
virtual void Hello();
}
-----
Parent* p = new Child;

In this case you've got what's called "A base pointer to a derived class". Since Hello is virtual, calling

p->Hello();

Will actually call Child::Hello(). That's polymorphism.

Make any sense?

Share this post


Link to post
Share on other sites
i guess my main confusion was i didn't understand which function would be called when the parameters were ambiguous. for example, lets say that the Hello(Son *p); function wasn't a member of the Parent class. if i did:

Parent Dad;
Son son;

Dad.Hello(&son);

this would call the Hello(Parent*) version of the function, no? i guess i just didn't understand which function it would call when both functions where defined. isnt this considered polymorphism when the son pointer is treated as a Parent pointer? i guess thats what i thought, anyway [smile]. i already understand the purpose of and how to use virtual functions though. thanks again.

@stormrunner

thanks, ill check that out.

Share this post


Link to post
Share on other sites
graveyard,

Now I understand your question. When a class defines multiple functions, each with the same name, but taking different parameters, its called function overloading. This you probably already knew.

If the parameters happen to be derived from each other, the compiler doesnt care. It will first try and resolve it against the class which is being passed in. If it cant, it'll try and find a compatible type, such as a parent.

So if Child derives from Parent as in our previous examples..and a function is defined which takes both a Parent and a Child, then passing in a Child will call the one which expects a child. However, if there is no function which takes a child, it will call the one that expects a parent.

And no, treating a child pointer as a base pointer isn't polymorphism. Its just a benefit of Inheritance. Polymorphism as I said before is when you have a base pointer to a derived class, and through the use of virtual functions, are still able to call child functions. Cheers and Good Luck!

Share this post


Link to post
Share on other sites
thanks J, that was the answer i was looking for.

what about in this situation?

Parent mom,*dad;

dad = new Son();

mom.Hello(dad);

will it call the *Son version here, or the Parent version? i totally forgot to ask this and this was my main question =).

Share this post


Link to post
Share on other sites
i was curious as well, and tested it. it will call the Hello(Parent*) version. however, mom.Hello((Son*)dad) calls the son version.

Share this post


Link to post
Share on other sites
Quote:
Original post by graveyard filla
thanks J, that was the answer i was looking for.

what about in this situation?

Parent mom,*dad;

dad = new Son();

mom.Hello(dad);

will it call the *Son version here, or the Parent version? i totally forgot to ask this and this was my main question =).

It will always check for a function the corresponds exactly with the type of the variable expression first, and only check for compatible types if an exact match could not be found. Since the variable dad is a Parent* (despite what it acutally points to), Hello(Parent*) will be called.

Another thing to not is that derived classes are NOT considered compatible types (unless you define a conversion yourself). This is because there is no way to guarenttee that your Parent* is also a Son* (without RTTI), whereas base classes are considered compatible since you can guarenttee that a Son* is also a Parent*.

Share this post


Link to post
Share on other sites
yup, When resolving parameters, the "type" of the pointer is always evaluated.

So a base pointer to a derived class is still a base pointer. It just points to an object not of the same type. As storm already said, it would call the parent version, not the derived version, since the pointer is of the parent type.

Think of it this way, whenever something expects a pointer, it will treat it first as the designated type ( base or child ) and then check for any compatible types.

Whenever you're calling a function ON a pointer( ex: foo->bar() ), it will call the version of that pointer type, unless the function is virtual, in which case it will check what the pointer is "actually" pointing to.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement