I always think of having to use pointers for polymorphism. Using the canonical example:
DrawEngine::render(Shape *shape)
{
shape->draw();
shape->visible(true);
}
And passing in pointer to various Shape derived classes. Does it work the same with references?
DrawEngine::render(Shape &shape)
{
shape.draw();
shape.visible(true);
}
Is it even valid to do:
engine.render(myTriangle); // myTriangle instance of class derived from Shape
If this works, are there any differences between the two cases? I tried to find information in Stroustrup, but I found nothing.
I reopened this because I wanted to explore just a tad more.
So at least one difference is dynamic_cast. For me, polymorphism includes the use of dynamic_cast.
Can I go
Rhomboid & r = dynamic_cast<Rhomboid &>(shape);
What happens if the cast fails? Is this any different?
Rhomboid * r = dynamic_cast<Rhomboid*>(&shape);
Polymorphism is one of the fundamental principles of Object-Oriented Software. The term typically means that something that can have multiple forms. In object-oriented methodology, polymorphism enables writing programs that have late binding references.
References are used to refer an existing variable in another name whereas pointers are used to store address of variable. References cannot have a null value assigned but pointer can. A reference variable can be referenced by pass by value whereas a pointer can be referenced but pass by reference.
(*) Genericity, the type of polymorphism provided by templates, doesn't need pointers nor references.
Polymorphism only works with non-value types: references and pointers. And since references can only be bound once, you cannot really use them in standard containers.
With regard to polymorphism, references work just like pointers.
Regarding dynamic_cast
, a failed cast produces a nullpointer with pointers, and results in a throw of a bad_cast
(IIRC) exception with references.
One reason is that there's no such thing as a valid null-reference.
And possibly another reason (but it could just be an unintentionally useful emergent feature) is that sometimes one needs the exception and sometimes one needs the easy-to-check nullpointer, and no matter whether you have a reference or pointer at hand it takes at most a dereferencing or address operator to obtain the behavior you want.
Cheers & hth.,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With