C ++ interview question 1: Can virtual functions be called in constructor and fictitious functions ?, Constructor
C ++ interview question 1: Can virtual functions be called in constructor and fictitious functions?
- You can call virtual functions in constructor and fictitious functions. The compiler will not report errors.
- C ++ primer is the best choice
- Because the class construction order is from the base class to the derived class, the virtual function does not show polymorphism when calling the virtual function in the constructor.
- The class structure is from the derived class to the base class. When you call the class destructor at a certain level of the inheritance level, it means that the derived class has been partially destructed, so no polymorphism is displayed.
- Therefore, if a pure virtual function declared in the base class is called in the destructor of the base class, an error occurs in the compiler.
Class Base {public: Base () {Fuction ();} virtual void Fuction () {cout <"Base: Fuction" <endl ;}; class: public Base {public: A () {Fuction ();} virtual void Fuction () {cout <"A: Fuction" <endl ;}}; // What will be output when an object of A is defined in this way? A a; the first call should be correct, but what is the result? Many people will say that output: A: Fuction A: Function is output according to the above situation, that is, when constructing the Base, that is, when the Base constructor calls Fuction, it calls the Fuction of subclass A. In fact, A has not yet started to construct, so that the function behavior is completely unpredictable, obviously this is not the case. The actual output result is: Base: FuctionA: Fuction.
Example 2:
# Include <iostream> using namespace std; class A {public: A () {cout <"A constructor"; Test ();}~ A () {cout <"A destructor"; cout <"A: Test ()" <endl;} virtual void Test () {cout <"A: Test ()" <endl ;}; class B: public A {public: B () {cout <"B constructor "; test ();}~ B () {cout <"B destructor"; Test () ;}virtual void Test () {cout <"B: Test () "<endl ;}}; int _ tmain (int argc, _ TCHAR * argv []) {A * pA = new B (); call the constructor to output A constructor: a: Test () B call constructor B: Test () cout <"dynamic call:"; pA-> Test (); the original pointer type is PA, the actual pointer type is B. Because it is A virtual function, B: Test (delete pA is called according to the actual type. Because the destructor of A is not A virtual function, it is called according to the original type pointer, if virtual is added to the destructor of A, the output result is B. The Destructor B: Test A is A: Test return 0 ;}
Example 3:
# Include <iostream> using namespace std; class A {public: void virtual f () {cout <"A" <endl ;}}; class B: public A {public: void virtual f () {cout <"B" <endl ;}}; int main () {A * pa = new (); pa-> f (); this is obviously a B * pb = (B *) pa; pb-> f (); this forces the pa to be copied to pb, therefore, pb points to A delete pa and pb. The addresses pointed to by pa and pb are deleted, but the pa and pb pointers are not deleted. The floating pointer pa = new B (); pa-> f (); B pb = (B *) pa; pb-> f (); B return 0;} conclusion: virtual functions are called based on the actual pointer type, other functions are called based on the original type.
Whether virtual functions can be called in constructor and destructor
1.
If a class cannot be a base class, do not declare that the Destructor is a virtual function, which consumes space.
2. Abnormal exit of the Destructor will lead to incomplete structure and Memory leakage. It is best to provide a management class, and provide a method in the management class to analyze the structure. The caller then decides the next operation based on the result of this method.
3. Do not call virtual functions in constructors. When constructing a base class, the virtual function is non-virtual and does not go to the derived class. It is both a static binding. Obviously, when we construct a subclass object, we first call the base class constructor to construct the base class part of the subclass. The subclass has not yet been constructed and has not been initialized, if you call a virtual function in the construction of the base class, it is very dangerous to call a non-initialized object if you can, therefore, in C ++, you cannot call the virtual function implementation of the subclass when constructing the parent class object. But it doesn't mean you can't write programs that way,
The compiler will not report an error if you write this statement. 4. Do not call virtual functions in destructor. During the analysis, the sub-class destructor will be called first to parse the sub-class part of the object, and then the anti-constructor part of the base class will be called, if you call a virtual function in the destructor of the base class, it is very dangerous to call the function in the subclass object that has been destructed. 5. Remember to call the copy function of the base class to copy the part of the base class when writing the copy function of the derived class.
The constructor cannot be a virtual function, but why is there a virtual constructor?
VIRTUAL functions (udfs) are also called DYNAMIC functions (DYNAMIC) in some languages. VIRTUAL functions are called to determine the specific function.
Objects must be created by Constructors (like nonsense). Therefore, constructors must have content and cannot be empty. (Empty virtual functions, such as Abstract Functions and pure virtual functions)
However, different child classes have different processing methods, so the constructor should be "virtual", that is, it should be able to rewrite the quilt class.