Reputation: 81
env:centos, gcc 4.8.5 codes like this :
#include <iostream>
using namespace std;
class Base{
public:
virtual void Func()
{
cout << "base" << std::endl;
}
virtual void Func2()
{
Func();
}
virtual ~Base() {
Func();
}
};
class Dev : public Base{
public:
virtual void Func()
{
cout << "Dev" << endl;
}
};
int main()
{
Dev d;
d.Func2();
return 0;
}
and print :
Dev
base
My question is why dose virtual function have different print in normal function and destructor ?
my teachers tell me, one obj has self's virtual point and table.Derived class rewrites a function in base class,then derived class rewrite the address of this function in virtual table. When we call virtual function, we can get the address of derived class funcion, so we call this function in derived class. but why dose we call base class function in destructor ?
I think every class has self's virtual table. When we call function in class, the compiler will find the most top virtual table. In destructor, derived class has been dropped by compiler, then TopMost virtual table is BaseClass, so Compiler call base function .
Upvotes: 0
Views: 88
Reputation: 36617
The C++ standard requires that a call of a virtual function of a class in a destructor of that class calls the version for that class or for a base (not a version overridden by a derived class). This has been true in all evolutions of the C++ standard.
For example, the 1998 standard, Section 12.7 "Construction and Destruction" para 3 says (bold emphasis mine)
Member functions, including virtual functions (10.3), can be called during construction or destruction (12.6.2). When a virtual function is called directly or indirectly from a constructor (including from the mem-initializer for a data member) or from a destructor, and the object to which the call applies is the object under construction or destruction, the function called is the one defined in the constructor or destructor’s own class or in one of its bases, but not a function overriding it in a class derived from the constructor or destructor’s class, or overriding it in one of the other base classes of the most derived object (1.8). If the virtual function call uses an explicit class member access (5.2.5) and the object-expression refers to the object under construction or destruction but its type is neither the constructor or destructor’s own class or one of its bases, the result of the call is undefined.
The wording has changed in subsequent evolutions of the standard, but the meaning (in this sense, at least) has not. For example, the C++17 working draft, Section 15.7 "Construction and Destruction" [class.cdtor] (again, bold emphasis mine)
Member functions, including virtual functions (13.3), can be called during construction or destruction (15.6.2). When a virtual function is called directly or indirectly from a constructor or from a destructor, including during the construction or destruction of the class’s non-static data members, and the object to which the call applies is the object (call it x) under construction or destruction, the function called is the final overrider in the constructor’s or destructor’s class and not one overriding it in a more-derived class. If the virtual function call uses an explicit class member access (8.2.5) and the object expression refers to the complete object of x or one of that object’s base class subobjects but not x or one of its base class subobjects, the behavior is undefined.
Upvotes: 3