C++ Polymorphism Question
DavidZemon
Posts: 2,973
Given that -fno-rtti stands for "Force no runtime type information", I have a question regarding polymorphism when used (compiled) with this option.
I have code like this and it compiles. It's broken at the moment... so I'm not sure if it works... but it compiles. I would think that, if the program were incapable of determining the type of `instance` within myFunc(), then it wouldn't compile because it doesn't know which version of foo() to call. And if it simply always calls Parent::foo() within myFunc(), what is the point of the virtual keyword when compiled with -fno-rtti?
Thanks,
David
EDIT
I compiled this on x86 and it does indeed work - quite magically I'd say. It printed both "Parent called" and "child called". Magic I tell you.
#include <stdio.h> class Parent { public: virtual void foo () { printf("Parent called!\n"); } int x; }; class Child : public Parent { public: void foo () { this->Parent::foo(); printf("Child called!\n"); } }; void myFunc (Parent &instance) { instance.foo(); }; int main () { Child instance; myFunc(instance); return 0; }
I have code like this and it compiles. It's broken at the moment... so I'm not sure if it works... but it compiles. I would think that, if the program were incapable of determining the type of `instance` within myFunc(), then it wouldn't compile because it doesn't know which version of foo() to call. And if it simply always calls Parent::foo() within myFunc(), what is the point of the virtual keyword when compiled with -fno-rtti?
Thanks,
David
EDIT
I compiled this on x86 and it does indeed work - quite magically I'd say. It printed both "Parent called" and "child called". Magic I tell you.
Comments
This code runs fine on my ActivityBot.
I was thinking there is something odd about your: Never seen that done before.
It works but is more often written as just: Which generates exactly the same code.
I have a funny feeling that Child::foo() needs to be declared virtual to use polymorphism the right way. Otherwise if you declare a Child and call foo(), it will call Child::foo() but if you declare a Parent pointer and assign it to a Child object, it will call Parent::foo() instead of Child::foo() because the vtable of Child will contain a pointer to Parent::foo() even though there is a Child::foo() declared because your Child::foo() is not virtual.
Unless I'm mistaken, this is true (and won't generate a compiler error) regardless of whether RTTI is enabled.
===Jac
Well, I just compiled the thing using your main() function and the output is the same whether the child::foo is virtual or not. That is this: Produces this: Make Child::foo virtual and the result is the same.
I don't think there is a vtable involved in these cases. The compiler can find the correct functions to call at compile time.
For polymorphism to work, the polymorphic functions must be declared virtual in all class definitions.
In a scenario where Child1 and Child2 are derived from the Parent class, and each has a virtual member function foo, calling the foo function using a pointer to, or an instance of, either Child1 or Child2 will call the appropriate class member function foo.
Where the parent member function foo has no meaningful implementation it is traditionally declared as a pure virtual function - otherwise it is generally invoked by the derived member function to process inherited data members or execute member functions belonging to the Parent class alone.
The use of this->Parent::foo is, of course, redundant and not good C++ style. The compiler takes care of using this in relation to member function calls.
Regards,
Neil Darlow
Vehicle
- Truck
- Car
- Plane
- Boat
If I create a Car object and store its address in a Vehicle pointer there's not much magic. The object is a car, however the pointer I use is type Vehicle so the only methods I can use via that pointer are those that work with any Vehicle. So lets say all Vehicles can Move(), Turn(), Start(), Stop(), then you can use all those functions and they will call the appropriate functions in your Car, Boat, or Plane object via the v-table. You can't however tell if any of your vehicles are Planes vs Boats vs Cars. So if you need to call Car::ChangeTire() and all you have is a Vehicle pointer.... you are boned. RTTI lets you figure out that this Vehicle pointer is actually a Car and that you can safely cast it and call Car::ChangeTire(). That's my understanding at least.
Your code has got to be able to live with the least common denominator aspect of the class hierarchy if you don't use RTTI.
Right, a class that wants to inherit from a pure abstract class with virtual functions must implement the virtual functions.
Polymorphism is achieved with virtual functions. RTTI is not necessary.
RTTI can be useful, but needing it to choose the right class defeats the idea of polymorphism to a large extent.