1. Do not call virtual functions in constructors
Conceptually, the work of a constructor is to initialize an object. The constructed object is considered "not fully generated" until the constructor is complete. When an object of a derived class is created, if a virtual function is called in the constructor of its base class, then the constructor of the derived class is not executed, and the called function (the virtual function of the derived class) may operate on a member that has not yet been initialized , which will cause the disaster to occur.
2. Do not call virtual functions in destructors
Similarly, a virtual function is called in a destructor, and the entry address of the function is statically determined at compile time. That is, a real call is implemented rather than a virtual call.
Examine the following examples.
#include <iostream>using namespace std;class A{public: virtual void show(){ cout<<"in A"<<endl; } virtual ~A(){show();}};class B:public A{public: void show(){ cout<<"in B"<<endl; }};int main(){ A a; B b;}
The result of the program output is:
In A
In A
When object B of Class B exits the scope, the destructor for Class B is called first, and then the destructor for class A is called, and the virtual function show () is called in the destructor ~a (). From the output, the destructor of Class A does not have a virtual call to the show () call.
Conceptually, a destructor is used to destroy an object, and when an object is destroyed, the destructor of the class to which the object belongs is called, and then the destructor of its base class is called, so that when the destructor of the base class is called, the "aftercare" work of the derived class object is completed. It is meaningless to call the version of the function defined in the derived class at this time.
Therefore, in general, you should avoid calling virtual functions in constructors and destructors, and if you must do so, it is necessary to be clear that this is a call to a virtual function actually .
=============================== Supplement =======================
Effective C + + clause 9 It is clear that the virtual function is not called in the constructor, and the destructor is similar
I guess your doubts lie in the fact that you don't understand the order in which the base class and the derived class destructors are executed, when the derived class in C + + calls the constructor of the base class before invoking the constructor of the derived class, and instead calls the constructor of the derived class before calling the base class's destructor.
If an object of a derived class is to be refactored, the destructor of the derived class is called first, and then when the destructor of the base class is called, a virtual function is encountered, at which time there are two options: Plan A is the base version of the virtual function called by the compiler, and the virtual function loses the meaning of the correct version of the runtime invocation; B is the compiler calls the derived class version of this virtual function, but at this point the derived class part of the object has been destroyed, "data members are considered undefined values", this function call will cause unknown behavior.
In fact, the compiler is using plan A, if the virtual function of the base class version is not pure virtual implementation, there will be no serious error occurs, but you will still be confused virtual function mechanism failure, not to be "a direct ticket to the overnight debugging", so effective C + + recommended not to do so
(It is important to understand the order in which constructors are initialized in inheritance (derived classes after the base class), the order in which destructors are called (first derived class))
The 10th question of "C + +" for College Recruiting interview C + + does not call virtual functions in constructors and destructors