The process of doing the project, encountered a problem.
The problem can be abstracted to the following question:
Ordinary people eat chopsticks, children eat spoon.
classpeople { Public: voideat () {get_util_to_eat (); } Virtual voidget_util_to_eat () {std::cout<<"people get chopsticks"<<Std::endl; }};classChildren: Publicpeople { Public: voidget_util_to_eat () {std::cout<<"Children get Scoop"<<Std::endl; }};intMain () {people* people =NewChildren (); People-eat (); return 0;}
Output Result:
Get Scoop
This, of course, is in line with our expectations.
Because people is not a virtual function, the above program calls the Eat method in people, which involves a concept that I have been vague about, how to invoke a virtual method in a class method.
This involves a question that has to be said before:
class a {public: void print () { "I am A" << Std::endl; }}; int Main () { a* a = NULL; A-print (); return 0 ;}
The above code will output what, according to the intuitive sense of NULL how the method can be called, the core bar.
But in fact, the output is:
I am A
When invoking a class function, the C + + compiler does not control whether the class is empty, but instead passes the address of the class as the this pointer to the function.
A->print (), it is equivalent to print (&A) in the compiler
There are cases where member variables are not used in print, so it is natural to run correctly.
Then look at the assembly code to get a better understanding of it. The following is the assembly code within the People class.
21 void eat () { 0x0000000000400bd2 <+0 ;: Push%rbp 0x 0000000000400bd3 <+1 ;: mov%rsp,% RBP 0x0000000000400bd6 <+4 > : Sub $0x10 ,%rsp 0x0000000000400bda <+8 ;: mov%rdi,-0x8 (%RBP)//RSP represents the first parameter, which is a pointer to the class
get_util_to_eat (); 0x0000000000400be9 <+23 ;: mov-0x8 (%RBP),%rax//Put the class pointer in the RAX register 0x0000000000400bed <+27 ;: mov (%rax),%< Span style= "COLOR: #000000" >rax//Take the first address value, which is the virtual table address 0x0000000000400bf0 <+ 30 ;: mov-0x8 (%RBP),%rdi//Put in RDI, the next time the function call takes the argument with 0x0000000000400bf4 <+34 ;: mov (%rax),%rax//Remove the address of the function in the virtual table 0x0000000000400bf7 <+37 ;: callq *%rax//Call change function
The summary is that when entering a non-static member function of a class, the pointer to the class is carried by default (this), and then the member variable is used within the function, and the member method is equivalent to adding a this-> in front of it.
So back to the original question, the Chilren pointer was passed in the people::eat, so the Children::get_util_to_eat method was fetched from the virtual table and called when Get_util_to_eat was called.
C + + class intrinsic function call virtual function