Reputation: 11
I ran across the following behavior writing a simple program to learn about virtual destructors. What I wanted to do was print the name of each class and then compare to what type my pointer was pointing to. I put print statements in each destructor so I could see behavior when switching between virtual and non-virtual in the base class.
Code:
class TimeKeeper {....} //non-virtual destructor in base class
class AtomicClock : public TimeKeeper {...}
int main(){
std::cout << "TimeKeeper Name: " << typeid(TimeKeeper).name() << std::endl;
std::cout << "AtomicClock Name: " << typeid(AtomicClock).name() << std::endl;
TimeKeeper *ptk = new AtomicClock(rand());
std::cout << "ptk is of type: " << typeid(*ptk).name() << std::endl;
delete ptk;
}
Here is the output:
TimeKeeper Name: 10TimeKeeper
AtomicClock Name: 11AtomicClock
ptk is of type: 10TimeKeeper
I am in the Base Class Destructor
However, when I change the TimeKeeper base class destructor to be virtual, the output is this:
TimeKeeper Name: 10TimeKeeper
AtomicClock Name: 11AtomicClock
ptk is of type: 11AtomicClock
I am in the Derived Class Destructor
I am in the Base Class Destructor
I understand why the dervied class destructor is being called, but I do not understand why the ptk type changed.
My Question is: Why does the type that ptk points to change when I switch to a virtual Destructor in TimeKeeper class? Or is this me not understanding how typeid works/how to use it?
Upvotes: 1
Views: 105
Reputation: 87997
It's the same as the difference between calling a virtual function or a non-virtual function. You can either use the type of the expression, or you can use the type of the object. In the case of
TimeKeeper *ptk = new AtomicClock(rand());
std::cout << "ptk is of type: " << typeid(*ptk).name() << std::endl;
the expression *pkt
has type reference to TimeKeeper
but the object referred to has type AtomicClock
. Either type could be printed by typeid
. What makes the difference is whether TimeKeeper
is polymorphic or not, that is whether it has any virtual methods (including a virtual destructor). If TimeKeeper
is polymorphic typeid
will use the type of the object otherwise the type of the expression.
Upvotes: 1