goldenmean
goldenmean

Reputation: 18956

C++ method overriding

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

Answers (4)

LihO
LihO

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Mike Seymour
Mike Seymour

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

sje397
sje397

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

Related Questions