If the parent virtual function is not overwritten, then this virtual function is completely meaningless.
If you have the following two classes of inheritance:
Class base{
Public
virtual void f () { cout<< "base::f ()" <<endl;}
virtual void g () { cout<< "base::g ()" <<endl;}
virtual void h () { cout<< "base::h ()" <<endl;}
void m () { cout << "base::m ()" << Endl;}
};
Class Derived:public base{
Public
void F () { cout << "Derived::f ()" << Endl;}
void g () { cout << "derived::g ()" << Endl;}
void m () { cout << "derived::m ()" << Endl;}
void N () { cout << "derived::n ()" << Endl;}
};
The first scenario is that we use virtual functions that are generally
base*p=newderived;
P->f (); derived::f ()
P->g (); derived::g ()
P->h (); base::h ()
P->m (); base::m ()
P->n ();//Compile Error
This is because both F and g are virtual functions, and the function has been overridden in the derived object (note that the override must be identical except for the function body definition, otherwise it cannot be overridden as a different function); H is a virtual function but not overridden , and N is only a member function of the derived class object, not the base class.
The meaning of the first line of code is to declare an object and cast the pointer of the object into a base type, and we know that when creating the derived class object, it must contain all the contents of the base class, after the pointer is cast, Only the object that needs to be executed or the data that needs to be manipulated will be found within the inherited base region. According to the above, F and g are overwritten, so the call will call derived, H is not overwritten, so call base H, and N is not in this area so it compiles an error: Cannot find this member.
Second case:
derived*p=newderived;
P->f (); derived::f ()
P->g (); derived::g ()
P->h (); base::h ()
P->m (); derived::m ()
P->n ();// derived::n ()
This time does not cast the pointer of the derived class object, this time will be in the derived area to find data and functions to execute, this time is actually in the body of the derived object, because F and g are covered, So there is only one f and G and the derived F and g;h are not covered but H is the base h; In short, the virtual function is called by the virtual function table. m has definitions in base and derived, but not virtual functions, so it is not overridden here and not overloaded, but is a function of two different classes, which is the first to see the M function in which class is called based on the function name as the identifier. This search process is a certain name lookup rules, especially in the multi-inheritance is more obvious, in C + + programming thought in the second volume of P374, there is a specific search rule description; Determine the class and then select the overloaded form of the function, For example, if m in base has an overloaded form of int, but not in derived, but is called with p->m (1) when called, in this case an error is given, because the name lookup rule determines that the M function in the derived class is used. However, there is no overloaded form of int in this class, and if this is overloaded in derived it is certainly not a problem, nor is it a problem if you do not define m in the derived class, because at this time the name lookup is determined by using the M function in the base class. In the base class, there is just the overloaded form of the int parameter of M, so there is no error, only the M function in the base class is called at this time.
In both cases, I have described two types of cases that I have seen in class inheritance: One is the invocation mechanism of virtual functions, and the other is the lookup and invocation mechanism of functions with the same name.
virtual function call (2) (reprint)