1. Use of virtual functions
First insert a piece of code
#include <iostream> #include <string> using namespace std; //Declare the base class Student class Student { public: Student(int, string,float); //Declaration constructor void display( );//Declare output function protected: //Protected member, which derived classes can access int num; string name; float score; }; //Implementation of Student class member function Student::Student(int n, string nam,float s)//Define constructor { num=n; name=nam; score=s; } void Student::display( )//Define output function { cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\n\n"; } //Declare the public derived class Graduate class Graduate:public Student { public: Graduate(int, string, float, float);//Declaration constructor void display( );//Declare output function private:float pay; }; // Implementation of member function of grade class void Graduate::display( )//Define output function { cout<<"num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay="<<pay<<endl; } //Note the use of pay (p) in the constructor Graduate::Graduate(int n, string nam,float s,float p):Student(n,nam,s),pay(p){} //Main function int main() { Student stud1(1001,"Li",87.5);//Define Student class object stud1 Graduate grad1(2001,"Wang",98.5,563.5);//Define the grade class object grad1 Student *pt=&stud1;//Defines the pointer variable pt that points to the base class object pt->display( ); pt=&grad1; pt->display( ); return 0; }
Print results:
It can be found that one line of pay is missing:
If you want to output all data members of grad1, of course, you can also use this method: call the display function through the object name, such as grad1 Display(), or define a pointer variable ptr pointing to the Graduate class object, then point ptr to gradl, and then call ptr - > display(). This is certainly possible, but if the base class has multiple derived classes, each derived class generates a new derived class, forming a class family of the same base class. Each derived class has a function display with the same name. In order to call the functions with the same name of different classes in the same class family in the program, multiple pointer variables pointing to each derived class must be defined. These two methods are inconvenient. They require different calling methods when calling functions with the same name of different derived classes.
This problem can be solved smoothly with virtual functions. Next, make some modifications to the program. When declaring the display function in the Student class, add a keyword virtual on the far left, that is
virtual void display( );
Originally, the base class pointer is used to point to the base class object. If it is used to point to the derived class object, the pointer type conversion is carried out. The pointer of the derived class object is first converted to the pointer of the base class, so the base class pointer points to the base class part of the derived class object. Before the program is modified, the member function in the derived class object cannot be called through the base class pointer. The virtual function breaks through this limitation. In the base class part of the derived class, the virtual function of the derived class replaces the original virtual function of the base class, so when the base class pointer points to the derived class object, the virtual function of the derived class is invoked when the virtual function is invoked. It should be noted that the above effect can be achieved only after the virtual function is declared with virtual. If it is not declared as a virtual function, it is not possible to attempt to call a non virtual function of a derived class through a base class pointer.
Virtual functions are used:
1. Declare the member function as virtual in the base class.
In this way, the function can be redefined in the derived class, given new functions, and can be easily called. Virtual does not need to be added when defining virtual functions outside the class.
2. Redefining this function in a derived class requires that the function name, function type, number and type of function parameters are all the same as the virtual function of the base class, and redefining the function body according to the needs of the derived class.
C + + stipulates that when a member function is declared as a virtual function, the functions with the same name in its derived classes will automatically become virtual functions. Therefore, virtual can be added or not when the derived class redeclares the virtual function, but it is customary to add virtual when declaring the function at each layer to make the program clearer. If the virtual function of the base class is not redefined in the derived class, the derived class simply inherits the virtual function of its direct base class.
3. Define a pointer variable to the base class object and make it point to the object in the same class family that needs to call the function.
4. This virtual function is called through the pointer variable. At this time, the function with the same name of the object pointed to by the pointer variable is called.
By combining the virtual function with the pointer variable pointing to the base class object, it is convenient to call the functions with the same name of different classes in the same class family, as long as you point to it with the base class pointer first. If the pointer constantly points to objects of different classes in the same family, you can constantly call functions with the same name in these objects. Just like what I said before, keep telling the taxi driver where to go, and then the driver will take you to where you want to go.
Description required; Sometimes, the non virtual function defined in the base class will be redefined in the derived class (such as the area function in example 12.1). If the member function is called with the base class pointer, the system will call the member function of the base class part of the object; If the member function is called with a derived class pointer, the system will call the member function in the derived class object. This is not a polymorphic behavior (using different types of pointers) and does not use the function of virtual function.