Let's start with a few questions:
Why there should be virtual functions, what virtual functions are, how to define virtual functions, and how virtual functions work.
Let's follow these questions;
We define fa as the parent class and son as the child class
(1) Why virtual functions
All C + + concepts are used to solve problems, and virtual functions are no exception. When we define A regular function A, the formal parameter of this function is fa class. Because son is A superset of FA, we can pass son to A. This is reasonable, but there will be A situation. If there is the same function B in FA class and son class [the function characteristics are the same], then B in FA will be called. However, if we pass son to A, we want to call B in A, but I'm sorry, because although we pass son, but the type is fa, so the specified function is still B in FA, then the virtual function will work at this time;
[it must be noted that the type of the formal parameter is pointer type or reference type, otherwise the type conversion will be forced. If the type conversion is forced, the formal parameter is essentially fa type, so there will be no virtual function]
(2) What are virtual functions:
According to the above question, we probably know what the virtual function is, that is, the function with priority. We declare B as the virtual function in fa, just like saying to the system, hey, the priority of this function is low. If we call the function with the same name of the subclass of this class, we will give priority to calling the function with the same name of the subclass.
This dish understands that this priority is that if the pointer type is a parent class, but the pointer points to a child class, declaring the virtual of the parent class pointed to by the pointer type is to say to the system: "Hey, don't use the function with the same name of the parent class, but use the function with the same name of the child class pointed to by the pointer";
(3) How to define virtual functions:
This is actually very simple. We just need to add the virtual keyword before the return type declaration of the function:
class g_fa { public: virtual void GetName() { std::cout << "grandfather" << std::endl; } };
However, if we'd better mark the non virtual function with override, it can increase readability;
(4) How virtual functions work:
We define three classes, g_fa, fa, son, where g_fa is the parent of fa and fa is the parent of son:
#include<iostream> #include<cstring> #include"head.h" #include<string> class g_fa { public: void GetName() { std::cout << "grandfather" << std::endl; } }; class fa:public g_fa { public: void GetName() { std::cout << "father" << std::endl; } }; class son :public fa{ public: void GetName() { std::cout << "son" << std::endl; } }; void GetName(g_fa &mid) { mid.GetName(); } int main() { g_fa g_fa; fa fa; son son; g_fa.GetName(); son.GetName(); father.GetName(); }
The operation results are normal:
But if we call the regular GetName function:
This also seems reasonable because the formal parameter of the function is g_fa, but you should know that because it is a reference type, the essence of the reference type is a const pointer, and the pointer will not be type converted. At most, we know the type of the variable pointed to, so we pass son in the past, and mid is still a pointer to the son class.
What if we want to call the GetName function in the son class?
We can put G_ The GetName function in the FA class is marked as a virtual function, that is, the final code is:
#include<iostream> #include<cstring> #include"head.h" #include<string> class g_fa { public: virtual void GetName() { std::cout << "grandfather" << std::endl; } }; class fa:public g_fa { public: void GetName() { std::cout << "father" << std::endl; } }; class son :public fa{ public: void GetName() { std::cout << "son" << std::endl; } }; void GetName(g_fa &mid) { mid.GetName(); } int main() { g_fa g_fa; fa fa; son son; GetName(g_fa); GetName(fa); GetName(son); }
The operation result is:
This means that G is not called_ GetName function in FA;
Interestingly, if we declare the GetName function virtual in fa, we will still get the same result;
Just verified the above sentence "Hey, don't use the function with the same name of the parent class, but the function with the same name of the subclass pointed to by the pointer";
This is the function of virtual function;