Reputation: 47995
I'm just curious. Here for example:
#include <iostream>
class Polygon {
protected:
int width, height;
public:
Polygon (int a, int b) : width(a), height(b) {}
int area() { return 0; };
};
class Rectangle: public Polygon {
public:
Rectangle(int a,int b) : Polygon(a,b) {}
int area() { return width*height; }
};
int main () {
Polygon * ppoly1 = new Rectangle (4,5);
std::cout << ppoly1->area() << std::endl;
delete ppoly1;
}
Can I call the area()
function of the object Rectangle
without set virtual area()
on Polygon
? Or it's impossible and Rectangle
's area()
will always be ignored without parent's virtual
?
Upvotes: 1
Views: 85
Reputation: 123084
If the function is not virtual, the compiler decides what function to call based on the type of the pointer (not on the actual type of the object), thus you can use a cast:
std::cout << static_cast<Rectangle*>(ppoly1)->area() << std::endl;
WARNING: The static cast is fine in this case, because you know for sure that the cast will succeed. In general this is not the case and you might get undefined behaviour if the cast does not succeed.
Also note, that the code you show here (I assume that this is just a simplified example) is a typical example for declaring the method virtual. Only if you have strong reasons not to do so you would look for a different solution (e.g. take a look at @axalis answer).
Upvotes: 6
Reputation: 6046
One possibility is compile-time polymorphism (CRTP):
template<class IMPL_T>
class Polygon {
protected:
int width, height;
public:
Polygon (int a, int b) : width(a), height(b) {}
int area() { return static_cast<IMPL_T *>(this)->area(); };
};
class Rectangle: public Polygon<Rectangle> {
public:
Rectangle(int a,int b) : Polygon(a,b) {}
int area() { return width*height; }
};
But note that then you cannot have a base class pointer (because base of each object is a different type). The use is, again, via templated calls.
In cases where you really need a runtime polymorphism (i.e. pointer to a base class), virtual call is normally the best solution, it is not likely you'll be able to roll out something better on your own (for example, replacing by switch on type getter combined with static casts is not only uglier but in many cases also worse performance, and dynamic_cast is much slower than calling a virtual method).
Upvotes: 2
Reputation: 93334
Can I call the area() function of the object Rectangle without set virtual area() on Polygon?
Yes, you can static_cast
a Polygon*
to a Rectange*
if you are sure that the pointer is actually pointing to a Rectangle
:
Polygon * ppoly1 = new Rectangle (4,5);
auto asRectangle = static_cast<Rectangle*>(ppoly1);
std::cout << asRectangle->area() << std::endl;
Upvotes: 0