We know that in the same class it is not possible to define two functions with the same name, the same number of arguments, and the same type, or "duplicate definition". However, in a class's inheritance hierarchy, functions that have the same name, the same number of arguments, and different types can appear in different hierarchies. For example, in example 12.1 (see a typical example of C + + polymorphism) in the program, the area function is defined in the Circle class, and an area function is defined in the derived class cylinder of the Circle class. These two functions are not only the same name, but also have the same number of parameters (all 0), but the function is different, the function body is different. The function of the former is to seek the area of the circle, the latter is to seek the surface area of the cylinder. This is legal because they are not in the same class. The compiled system determines which object to invoke, based on the principle of overwriting with the same name. The member function area in the derived class cylinder is called in the example 12.1 program with Cy1.area (). If you want to call the area function of the direct base class circle in Cy1, it should be represented as cy1. Circle::area (). Use this method to distinguish between two functions of the same name. But it's not convenient.
It is proposed that the same invocation can be used to invoke a derived class and invoke a function of the same name as the base class. Instead of calling functions of the same name in different derived hierarchies through different object names in the program, they are called by pointers. For example, use the same statement "Pt->display ();" You can invoke the display function in a different derived hierarchy by assigning a different value to the pointer variable pt before the call (making it point to a different class object).
For example, you have to go to a place to do business, if you take a bus, you must determine the destination in advance, and then take the bus line to reach the destination. If you take a taxi instead, you do not have to check the route, because taxis can go anywhere, as long as the car after the temporary tell the driver where to go. If you want to access multiple destinations, just tell the driver the next destination after arriving at a destination, obviously, "hit" is more convenient than taking the bus. No matter where you go, you can take the same taxi. This is an example of a different purpose that can be achieved through the same form.
Virtual functions in C + + are used to solve this problem. Virtual functions allow you to redefine a function with the same name as a base class in a derived class, and you can access a function of the same name in the base class and derived class by using a base class pointer or reference.
Please analyze example 12.2. This example does not use virtual functions at the beginning, and then discusses the use of virtual functions.
[Example 12.2] The base class and the derived class have the same name function. In the following program, student is the base class, and graduate is a derived class that has a function that has the same name as display.
#include <iostream>#include<string>using namespacestd;//declaring a base class studentclassstudent{ Public: Student (int,string,float);//declaring Constructors voidDisplay ();//declaring output Functionsprotected://Protected members, derived classes can access intnum; stringname; floatscore;};//implementation of Student class member functionsStudent::student (intNstringNamfloatS//Defining Constructors{num=N; Name=Nam; Score=s;}voidStudent::d isplay ()//Defining output Functions{cout<<"Num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\ n";}//declaring a common derived class graduateclassGraduate: Publicstudent{ Public: Graduate (int,string,float,float);//declaring Constructors voidDisplay ();//declaring output FunctionsPrivate:floatPay ;};//implementation of graduate class member functionsvoidGraduate::d Isplay ()//Defining output Functions{cout<<"Num:"<<num<<"\nname:"<<name<<"\nscore:"<<score<<"\npay="<<pay<<Endl;} Graduate::graduate (intNstringNamfloatSfloatp): Student (n,nam,s), Pay (p) {}//Main functionintMain () {Student stud1 (1001,"Li",87.5);//defines the Student class object Stud1Graduate Grad1 (2001,"Wang",98.5,563.5);//defines the Graduate class object Grad1Student *pt=&stud1;//defines a pointer variable to a base class object ptPt->display (); PT=&Grad1; PT-display (); return 0;}
The results of the operation are as follows:
NUM:1001 (STUD1 's data)
Name:li
score:87.5
NUM:2001 (data from the base class part of Grad1)
Name:wang
score:98.5
If you want to output all of the data members of GRAD1, you can of course use this method: Call the display function through the object name, such as Grad1.display (), or define a pointer to the Graduate class object, PTR, and then point PTR to the GRADL, Call again with Ptr->display (). This is certainly possible, but if the base class has more than one derived class, each derived class produces a new derived class that forms the class family of the same base class. Each derived class has a function display with the same name, and in order to invoke a function of the same type in the same family, define multiple pointer variables to each derived class. Both of these approaches are inconvenient, requiring different invocation methods when invoking functions of the same name in different derived classes, as mentioned earlier, to different destinations to take the specified different buses, one by one, and cannot be mistaken. It would be nice if you could invoke all of the same name functions in the same class in a different way.
This problem can be solved successfully with virtual function. Here is a little modification of the program, when declaring the display function in the Student class, add a keyword virtual to the left, i.e.
virtual void display ();
This declares the display function of the student class as a virtual function. Other parts of the program are not changed. To compile and run the program, please note the results of the analysis run:
NUM:1001 (STUD1 's data)
Name:li
score:87.5
NUM:2001 (data from the base class part of Grad1)
Name:wang
score:98.5
PAY=1200 (this one was not previously)
See! This is the magical effect of virtual functions. Now with the same pointer variable (pointer to the base class object variable), not only output the student STUD1 all the data, but also output the graduate Grad1 all the data, indicating that the GRAD1 display function has been called. In the same invocation form, "Pt->display ()", and PT is the same base class pointer, it is possible to invoke a virtual function of a different class within the same family. This is polymorphism, and different objects have different responses to the same message.
Note: A base class pointer is used to point to a base class object, and if it is used to point to a derived class object, a pointer-type conversion is made, and a pointer to the derived class object is first converted to a pointer to the base class, so the base-class pointer points to the base-class part in the derived class object. A member function in a derived class object cannot be called by a base-class pointer until the program is modified. Virtual functions break through this limitation, in the base class part of the derived class, the virtual function of the derived class supersedes 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 called when the virtual functions are called. It is important to note that only virtual functions are declared with virtual. If you do not declare a virtual function, it is not possible to attempt to invoke a non-virtual function of a derived class through a base class pointer.
The above function of virtual function is very useful. In object-oriented programming, the inheritance of classes is often used to preserve the properties of the base class to reduce the time for new class development. However, some member functions that inherit from the base class do not fully fit the needs of the derived class, for example, in Example 12.2, the display function of the base class outputs only the data of the base class, and the display function of the derived class needs to output data from the derived class. In the past we used to make the output function of the derived class different from the output function of the base class (for example, display and display1), but it would be inconvenient to have many different function names if the derived hierarchy were many. If you take a function with the same name, overrides with the same name occur.
The use of virtual functions is a good solution to this problem. You can see that when a member function of a base class is declared as a virtual function, it is allowed to redefine the function in its derived class, give it new functionality, and invoke a function of the same name with a pointer to a base class that points to a non-homogeneous object in the same class. The dynamic polymorphism implemented by virtual function is the same kind of object in the same family, and responds differently to the same function call.
Virtual functions are used in the following ways:
- Declare member functions as virtual functions in the base class with virtual.
This allows you to redefine this function in a derived class, give it new functionality, and be easily invoked. When you define a virtual function outside of a class, you do not have to add virtual.
- Redefining this function in a derived class requires that the function name, the function type, the number of function arguments, and the type are all the same as the virtual functions of the base class, and redefine 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 function with the same name in its derived class automatically becomes a virtual function. Therefore, when a derived class re-declares the virtual function, you can add virtual, or do not add, but it is customary to declare the function at each layer to add virtual, so that 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 immediate base class.
- Defines a pointer variable that points to a base class object and points it to the object in the same class of family that needs to call the function.
- This virtual function is called through this pointer variable, which is called the function with the same name as the object that the pointer variable points to.
By using a virtual function with a pointer variable to a base class object, you can easily invoke a function of the same name in the same class, as long as you point to the base class pointer. If the pointer constantly points to objects of the same class that are not homogeneous, you can constantly call functions with the same name in those objects. This is like saying, keep telling the taxi driver where to go, and the driver will send you where you want to go.
A non-virtual function defined in a base class is sometimes redefined in a derived class (such as the area function in Example 12.1), and if the member function is called with a base-class pointer, the system invokes the member function of the base class part in the object, or if the member function is called with a derived class pointer. The system calls the member functions in the derived class object, which is not a polymorphic behavior (using different types of pointers) and does not use the function of a virtual function.
The function overloads described previously dealt with the same-name function problem at the same level, while the virtual function handles the problem of the same-name function at different derived levels, which is horizontal overloading, which can be understood as vertical overloading. However, unlike overloading, the first of the virtual functions of the same family is the same, and the functions are overloaded with different headers (the number of arguments or different types).
(Original address: http://c.biancheng.net/cpp/biancheng/view/244.html)
[Go] what is a C + + virtual function, the function of virtual function and how to use