We know that when we sizeof a class, the member function of the class is not counted in the size of the object, which is why? Because the member function of a class is not part of an object, it is shared by all objects of the class, just like a static variable. If the virtual function is the same as the normal member function, then we cannot refer to the subclass's method by pointing to the base class pointer of the subclass, because we will not know which method to invoke, and polymorphism will not be able to talk about it. So how did the polymorphism come true?
- Virtual functions, virtual pointers, and virtual tables
We can do a little experiment.
class a{ public : int A; virtual void Myfun () {}}; class B:public a{ public : int b;}; B Obj_b;
Obj_b.a=1;
obj_b.b=2; A *p=&b;cout <<p<<endl ; cout <<& (p->a) <<endl;
cout<<p->a<< ' \ t ' <<* (& (P->a) +1) <<endl;
The value of P and & (p->a) is 4 bytes apart, and the last line outputs a value of 1, 2. We can infer that the distribution of obj_b in memory is first a type that occupies 4 bytes, then int a, and finally int B.
The initial 4 bytes are actually virtual pointers.
And the object of Class A in memory distribution is actually a virtual pointer and then int a.
If Class B inherits a, the virtual pointer and int A are inherited when the B is constructed, but the virtual table pointed to by the virtual pointer is different. If a virtual function is implemented in B, the entry address of the corresponding function in the virtual table will also change. So as to achieve the purpose of polymorphism.
Note that pointer p is not accessible to B, because P is a pointer of type A, and the access range of the visible pointer is determined by the type. So we access B through & (P->a) +.
So what is the case with multiple inheritance?
Multiple inheritance, for each base class that has virtual functions, the subclass inherits the corresponding virtual pointer and overwrites the virtual table.
I think a blog is very good to write a quote came over. The blog address is: http://www.cnblogs.com/CCQLegend/p/3270738.html
This pointer is different from what many people imagine, and its type is determined by the called function. Its type follows these two-point rules: (The way to tick the first address.) )
1. For non-virtual functions , the base address of the this pointer is the first address of the hierarchy object where the function is defined, and the range is the beginning of the hierarchy.
such as: Ia::ff ();
The this pointer type is the D0H-first address, ranging from the initial address to the DFH. (In fact, there is a memory hole, we do not struggle with this)
Derived::ff ();
The this pointer type is the C0H first address, ranging from the initial address to the e8h.
2. For virtual functions , the base address of the this pointer is the first address of the function's first declarator , and the scope is the beginning of the implementation .
such as: Ia::f ();
The this pointer type is the D0H-first address, ranging from the initial address to the DFH.
Derived::f ();
Its this pointer type is D0H-led, ranging from c0h to e8h.
Then when there is ia* a=new Derived ();
A->f (); That's how you access the B-member. Assuming that the first address d0h is stored in the Register Rax,
Rax-8
C + + virtual function implementation with this pointer