LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   polymorphism (https://www.linuxquestions.org/questions/programming-9/polymorphism-753691/)

icecubeflower 09-08-2009 07:39 PM

polymorphism
 
"A pointer to a derived class is type-compatible with a pointer to its base class."

I think this means you can declare a pointer of type-derived class and still make it point at an instance of the base class.

But can you declare a pointer of type-base class and make it point to an instance of a derived class?

And what I really want to know is can you make two different derived classes and declare a pointer to one yet make it point to a different derived class which is derived from the same base?

Sergei Steshenko 09-08-2009 08:43 PM

Quote:

Originally Posted by icecubeflower (Post 3675077)
"A pointer to a derived class is type-compatible with a pointer to its base class."

I think this means you can declare a pointer of type-derived class and still make it point at an instance of the base class.

But can you declare a pointer of type-base class and make it point to an instance of a derived class?

And what I really want to know is can you make two different derived classes and declare a pointer to one yet make it point to a different derived class which is derived from the same base?

I think the item in bold is not correct.

The point is that derived class may have more items (like added data and methods) which the base class does not have. So, if you dereference something through such a pointer, the dereferenced items may be invalid because they do not exist in the base class, but the pointer "thinks" they exist.

I.e. the items accessed through dereferencing won't simply exist; the dereferencing mechanism will point to irrelevant memory locations, etc.

nadroj 09-08-2009 08:43 PM

Quote:

But can you declare a pointer of type-base class and make it point to an instance of a derived class?
if im understanding your question correctly, then yes, this is the main/key feature of polymorphism. we define a class Vehicle with a pure virtual function "Honk". We create two derived concrete classes "Sedan" and "Truck", both of which were required to implement the Honk function. Now we can declare a pointer to the base class, Vehicle, and assign it to any class that extends Vehicle (directly or indirectly). Now if you call the "Honk" function on this pointer, its behaviour (i.e. "sound"), will vary depending on which type it is actually pointing to. That is, a "Honk" from a "Sedan" may behave ("sound") very different to the same "Honk" function of a "Truck" reference.

Quote:

And what I really want to know is can you make two different derived classes and declare a pointer to one yet make it point to a different derived class which is derived from the same base?
No, they are not compatible types. (though I use Java much more often than C++, which I assume your question is geared towards; therefore I am not as confident in this answer as it relates to C++).
Using the same high-level example above (abstract class "Vehicle", concrete child classes "Truck" and "Sedan"), say we change the "Sedan" class and add a new function, "Recharge", because its some electric car. If we declare a "Sedan" pointer, we cannot assign to it a reference to a "Truck", because they are incompatible types. "Sedan" has the "Recharge" function, "Truck" does not. They are only compatible at the "parent level", because that is the only place where they are common.

Remember that C++ allows multiple inheritance, so I am not sure of the correct answer in C++. Still, using the above example, lets add another class "Sedan-Truck" which is a "hybrid" (for whatever reason, good on gas but power of a truck), and it extends both "Sedan" and "Truck". This way, you could have 2 pointers: a pointer to a Sedan and a pointer to a Truck. You could assign both/either of these pointers the reference of a "Sedan-Truck", since this new child "is a" Sedan and also "is a" Truck. This isnt exactly what your question was, but just an FYI. You still cannot assign to a "Sedan" pointer a reference to a "Truck", because they, again, arent compatible types.

Im not sure if any of this answers your questions, though.

Sergei Steshenko 09-08-2009 09:16 PM

By the way, the thread should probably be called "Inheritance and pointers", not "polymorphism".

AFAIK polymorphism is when the same (rather, named the same way) methods/functions may have different interfaces/signature, like

Code:

double add_two_numbers(double, double);
double add_two_numbers(unsigned, double);
double add_two_numbers(float, double);
double add_two_numbers(float, int);

, etc - 'add_two_numbers' is polymorphic in this case.

And polymorphic functions/methods of the same name may have different number of arguments too.

nadroj 09-08-2009 11:23 PM

Quote:

Originally Posted by Sergei Steshenko (Post 3675154)
AFAIK polymorphism is when the same (rather, named the same way) methods/functions may have different interfaces/signature, like

Code:

double add_two_numbers(double, double);
double add_two_numbers(unsigned, double);
double add_two_numbers(float, double);
double add_two_numbers(float, int);

, etc - 'add_two_numbers' is polymorphic in this case.

And polymorphic functions/methods of the same name may have different number of arguments too.

what you are describing is function overloading, which is when you define a function with the same name but different signature.

polymorphism is basically when an objects behaviour is dynamically determined. in my example above, if we have a "Vehicle" pointer and its assigned a valid reference to an instance of one of its child classes ("Sedan" or "Truck"), if we call the "Honk" function, its behaviour is determined by the type of reference it happens to be pointing to. heres some silly pseudocode as an example:

Code:

Animal * myAnimal
Sedan mySedan = new Sedan
Truck myTruck = new Truck

myAnimal = mySedan
myAnimal.Honk // this calls the "Honk" function as implemented in class "Sedan", i.e. maybe produces a high pitched horn sound

myAnimal = myTruck
myAnimal.Honk // this calls the "Honk" function as implemented in class "Truck", i.e. maybe produces a low pitched horn sound


icecubeflower 09-08-2009 11:28 PM

Hey thanks you guys answered that pretty well. Except I'm pretty sure this is called polymorphism. At least that's what they call it here:
http://www.cplusplus.com/doc/tutorial/polymorphism/

Now what I wonder is what if you declare a "vehicle" pointer and make it point at an instance of "sedan". Would you be able to access the recharge function even though that function is specific to "sedan"?

I think I could try this on my own but I am afraid maybe it is not allowed but the compiler still lets you do it or I would learn the wrong lesson somehow.

Sergei Steshenko 09-08-2009 11:33 PM

Quote:

Originally Posted by icecubeflower (Post 3675296)
Hey thanks you guys answered that pretty well. Except I'm pretty sure this is called polymorphism. At least that's what they call it here:
http://www.cplusplus.com/doc/tutorial/polymorphism/

Now what I wonder is what if you declare a "vehicle" pointer and make it point at an instance of "sedan". Would you be able to access the recharge function even though that function is specific to "sedan"?

I think I could try this on my own but I am afraid maybe it is not allowed but the compiler still lets you do it or I would learn the wrong lesson somehow.

Yeah, you are correct on polymorphism, also here: http://en.wikipedia.org/wiki/Polymor...ed_programming .

Sergei Steshenko 09-08-2009 11:37 PM

http://www.codeproject.com/KB/cpp/PolyC.aspx - from "C" point of view.

nadroj 09-08-2009 11:51 PM

Quote:

Originally Posted by icecubeflower (Post 3675296)
Now what I wonder is what if you declare a "vehicle" pointer and make it point at an instance of "sedan". Would you be able to access the recharge function even though that function is specific to "sedan"

no, the "Recharge" function is only specific to "Sedan" class. the type of functionality your asking is quite common, but you have to either cast the instance or create a new pointer of this type, pointing to the instance... hopefully this pseudocode clears it up:

Code:

Vehicle * myVehicle = new Sedan

// to access the "Recharge" function, you must do one of the following:

// 1)

((Sedan) myVehicle)->Recharge

// 2)
Sedan * mySedan = (Sedan) myVehicle

mySedan->Recharge

either way, of course it boils down to casting it to the type that you know it is, and then you can call any method in the child and base class(es).

graemef 09-09-2009 02:32 AM

In polymorphism the typical approach would be to have a pointer to the base class, the contents of this pointer is currently null (or at least a nonsensical address). You can now assign the address of a new object to this pointer. This can be either an object of the base class or any derived class, in C++ this is done with the new keyword, and is checked at run time.

At compile time the compiler sees the pointer as a pointer to the base class so it will accept calls to any method in the base class, and at run time the appropriate class will be called (In C++ this is assuming that the method is virtual). This means that you cannot call a method of the derived class unless it is also in the base class. This can be tackled by putting an abstract version of the method in the base class and implementing it in every derived class.

Sergei Steshenko 09-09-2009 02:41 AM

Simplistically, OOP is counterintutive - in real life parents know everything about their (baby) children, in OOP children know everything about their parents (except for private/protected data/methods).

graemef 09-09-2009 02:47 AM

Quote:

Originally Posted by Sergei Steshenko (Post 3675465)
Simplistically, OOP is counterintutive - in real life parents know everything about their (baby) children, in OOP children know everything about their parents (except for private/protected data/methods).

Not at all. Parents know about the child based on what they already know. My parent know about a name and about a date of birth because they both have one, but since neither of my parents went to university why should they suddenly be endowed with the knowledge of what a degree is because I graduate from University?

Sergei Steshenko 09-09-2009 02:51 AM

Quote:

Originally Posted by graemef (Post 3675472)
Not at all. Parents know about the child based on what they already know. My parent know about a name and about a date of birth because they both have one, but since neither of my parents went to university why should they suddenly be endowed with the knowledge of what a degree is because I graduate from University?

I meant that in real life parents know about (baby) children details not inherited from parents, like illnesses (like cold, flue), sounds the babies make, their food preferences, their favorite toys, etc.

graemef 09-09-2009 03:11 AM

Quote:

Originally Posted by Sergei Steshenko (Post 3675475)
I meant that in real life parents know about (baby) children details not inherited from parents, like illnesses (like cold, flue), sounds the babies make, their food preferences, their favorite toys, etc.

But parents were children once, thus they had all of these properties, once. However you appear to be confusing the class (properties) with the object (specific details).

Sergei Steshenko 09-09-2009 12:10 PM

Quote:

Originally Posted by graemef (Post 3675494)
But parents were children once, thus they had all of these properties, once. However you appear to be confusing the class (properties) with the object (specific details).

No, I am not confusing, I am saying that OOP uses terms which in real non-programmatic life imply different relationships, and this makes OOP (somewhat) counterintuitive.


All times are GMT -5. The time now is 06:11 AM.