1. Non-virtual functions, call rules depend on the explicit type of the object. For example
A * a = new B ();
A->display ();
Called is the display () defined in Class A. And the object ontology is B-no relationship.
The 2.virtual function, which version is called, depends on the virtual function table. For example
A * a = new B ();
A->v_display ();
At this time, object a needs to find its own virtual function table, V_display () in the table is a function pointer, may point to the corresponding V_display function in the same class and call the corresponding version of V_display. In general, if B overrides V_display (), then B's V_display () is called, if no display () of a is called;
3. Pure virtual functions. In combination with 2 analysis, pure virtual functions are not defined in the parent class, and if the subclass inherits and still does not override and define the corresponding pure virtual function, then the subclass is also an abstract class and cannot initialize the object until a class defines the virtual function.
This class can initialize an object. The virtual function table related data of this function is maintained on this object.
About virtual function tables:
Typically stored in a fixed address of an object, we can even call some virtual functions directly from a virtual function table.
For example:
A * a = new B ();
A is the address of object A.
The address of a is coerced into an int pointer (int*) A, which is idealized to treat the object as an int array, because all of the object's data is stored in an adjacent block of addresses similar to the array rules, so converting a to int* is like converting an object into a set of int, Each int is actually an address. )
And what are the things stored in each of these addresses? Other do not know, the first storage is the virtual function table, inside is a group of addresses! We will dereference the first address:
* (int*) (a)
Then we get a first address that stores the virtual function table pointer and then strongly turn it into int*, so we get the first address of the virtual function table, which is
(int*) * (int*) (a)
This address can be calculated like int[], if +1 can get the next function of the virtual function table. But after all, the address of each function is obtained, so we also need to dereference it:
* (int*) * (int*) (a) This gives you a real function pointer! It's easy to get here, if the function we're calling is void (void) type, we create a function pointer type:
typedef void (*fun) (void)
Thus, if the function pointers obtained from the virtual function table above are also void (void), we can strongly convert them to the corresponding function pointer types
That
Fun Vfun = (fun) * (int*) * (int*) (a);
Vfun ();
Oh, selling Shaw's ...
I have a set of test code here:
#include <iostream>#include<string>using namespaceStd;typedefvoid(*fun) (void);classa{Private : strings; Public : Virtual voiddisplay (); Virtual voidV_display (); Virtual voidV_0_display ()Const=0;};classD | Publica{ Public: voiddisplay (); //void V_display (); voidV_0_display ()Const;};voidA::d isplay () {cout<<"A::d isplay"<<Endl;}voidA::v_display () {cout<<"A::v_display"<<Endl;}voidB::d isplay () {cout<<"B::d isplay"<<Endl;}//void B::v_display ()//{//cout << "B::v_display" << Endl;//}voidB::v_0_display ()Const{cout<<"B::v_0_display"<<Endl;}intMainintargcChar*argv[]) {A* A =NewB (); B* B =NewB (); Fun Vfun=NULL; Vfun= (Fun) * ((int*)*((int*) (a)) +0); cout<<"The address the first virtual function is"<< (int*)*((int*) (a) +0) <<Endl; cout<<"------------virtual Table-------------"<<Endl; Vfun (); Vfun= (Fun) * ((int*)*((int*) (a)) +1); Vfun (); Vfun= (Fun) * ((int*)*((int*) (a)) +2); Vfun (); cout<<"--------------------------------------"<<Endl; A-display (); A-V_display (); A-V_0_display (); ((B*) (a))display (); ((B*) (a))V_display (); ((B*) (a))V_0_display (); b-display (); b-V_display (); b-V_0_display (); ((A*) (b))display (); ((A*) (b))V_display (); ((A*) (b))V_0_display (); System ("Pause");}
Printing results are:
function is002fdc94------------virtual table-------------B::d isplaya::v_displayb::v_0_display--------- -----------------------------B::d isplaya::v_displayb::v_0_displayb::d isplaya::v_displayb::v_0_displayb:: Displaya::v_displayb::v_0_displayb::d isplaya::v_displayb::v_0_display Please press any key to continue ...
C + + polymorphism, virtual function mechanism, and virtual function table