Reputation: 18956
Is the Wikipedia example at this article about method overiding in C++ correct?
Please see the code below where I have mentioned a comment //INCORRECT
Slightly confused about overiding in C++ and run time polymorphism. What should this cast do?
#include <iostream>
class Rectangle {
public:
explicit Rectangle(double l, double w) : length(l), width(w) {}
virtual void print() const;
private:
double length;
double width;
};
void Rectangle::print() const { // print() method of base class
std::cout << "Length = " << this->length << "; Width = " << this->width;
}
class Box : public Rectangle {
public:
explicit Box(double l, double w, double h) : Rectangle(l, w), height(h) {}
virtual void print() const; // virtual is optional here, but it is a good practice to remind it to the developer
private:
double height;
};
void Box::print() const { // print() method of derived class
Rectangle::print(); // Invoke parent print() method.
std::cout << "; Height= " << this->height;
}
int main(int argc, char** argv) {
Rectangle rectangle(5.0, 3.0); rectangle.print();
// outputs:
// Length = 5.0; Width = 3.0
Box box(6.0, 5.0, 4.0);
// the pointer to the most overridden method in the vtable in on Box::print
//box.print(); // but this call does not illustrate overriding
static_cast<Rectangle&>(box).print(); // this one does
// outputs:
// Length = 5.0; Width = 3.0; Height= 4 // INCORRECT
//But it actually outputs Length = 6; Width = 5; Height = 4
getchar();
return 0;
}
Upvotes: 1
Views: 1265
Reputation: 42083
this line: static_cast<Rectangle&>(box).print();
has same effect as this code would have:
Rectangle & r = box;
r.print();
and also same effect as this code would have:
Rectangle * r = &box;
r->print();
It means that Box object was created (Box box(6.0, 5.0, 4.0);
= in runtime you see Box
) and it doesn't matter what is the type of pointer / reference where you store this object. The fact that you store box as a Rectangle*
is what you see in compile time.
Most important fact about overriding virtual methods is that about "which method will be called?" is decided in runtime.
Hope this helps.
Upvotes: 2
Reputation: 726479
Feel free to fix the comment in Wikipedia: the output should indeed be Length = 6; Width = 5; Height = 4
.
The other part is correct, though: the code where a Box.print()
is called even after the Box
reference has been statically cast to a reference to its superclass is indeed a demonstration of how overriding of a virtual method works in C++.
Another way to demonstrate the same point is through use of a pointer instead of a reference:
Rectangle *boxPtr = &box;
boxPtr->print();
Upvotes: 3
Reputation: 254431
The comment in the article was indeed wrong (and has now been fixed); it should have printed 6,5, and 4 as you say.
The point of the cast is to demonstrate that, even if you call the virtual function via a reference to the base class (Rectangle
), it will call the override associated with the actual type of the object (Box
) - you still get the three values printed by Box::print()
, rather than the two printed by Rectangle::print()
.
Upvotes: 2
Reputation: 41812
You're right - the output mentioned is incorrect.
The cast simply demonstrates that a box is a kind of rectangle (inheriting from it) and that even as a rectangle, the method override will still be effective and the Box
version of the print
method will be called.
Upvotes: 3