virtual function Implementation Mechanism

Source: Internet
Author: User

When it comes to the implementation of virtual functions, we have to talk about dynamic binding and static binding. Static linking means that the compiler can directly associate identifiers with stored physical addresses. Each function has a unique physical address, and when the compiler encounters a function call, it uses a mechanical language description instead of a function call to tell the CPU to jump to the address of the function and then manipulate the function. This process is done during the compilation process (note: The called function must be able to be determined at compile time), so static linking is also called a pre-early binding.      However, if you are using a function that cannot be determined at compile time, you need to use a dynamic binder, which is called when the program is running, so dynamic linking is also called a late-late binding. In C + + inheritance polymorphism, if you want to redefine a method of a base class in a derived class, declare it as a virtual function, and use a pointer or a reference to invoke its method to implement a dynamic union, otherwise the compiler defaults to a static union. Underestimate This example: Example1:

#include <iostream>
using namespace std;

class A
{
    public:
    void f() { cout << "A" << endl; } //注意此处的函数不是虚函数



};

class B : public A

    public:
        void f() { cout << "B" << endl;}
};
int main (void)
{

    A     a, *pa; 
    B     b;  
        

      a = b; //将子类对象赋给基类对象
      a.f();

      pa = &b; //用子类的对象的地址给基类指针初始化(符合赋值兼容规则)

      pa->f();

       

      return 0;
}

 
 

Operation Result:

A

A


cause: The compiler defaults to static, so the function f () is already dead during compilation, and although you redefine the method of F () in the subclass, the compiler does not know which function to call, so it only uses the static-inline function method. Example 2:

#include  <iostream>
Using namespace std;

Class a
{
    public:
    virtual void f ()  { cout <<  "A"  << endl; } //note that the virtual function

} is declared here;

Class b : public a
{    
    public:
        void f ()     { cout <<   "B" &NBSP;<<&NBSP;ENDL;}
};
int main  (void)
{
    a     a, *pa; 
    B    b;
       

        a = b; //将子类对象赋给基类对象,这样做不能实现动态联编,虚函数特性失效
        a.f();
        b.f();
        pa = &b;
        pa->f();
        A &aa = b; //定义成引用类型也是可以的
        aa.f ();

 

        return 0;
}


Operation Result:

A
B
B
B

Firstsummarize two programs, destructors class is not declared as virtual function, when a A = B, or a&a = b, a *a = &b, when the object is created and initialized, the method is selected based on the type of reference or pointer. This is the first program to run the results of the specific explanation (feel that you said the static is a bit abstract, do not know that this will not be easier to understand some of the explanation.) O (∩_∩) o~). If virtual is declared as a virtual function, the program chooses the method based on the type of the pair that the reference or pointer points to. This is the reason for the result of program two running. The effect of virtual function can be clearly seen by comparing two results. But what is its specific implementation principle? C + + uses a special form of dynamic linking to implement virtual function, called virtual function table. A virtual function table is a function lookup table that resolves calls to functions in a dynamic way. It provides a portal for each virtual function that can be called by a class object, so that when we manipulate the object of a subclass with a pointer or reference to a base class, this virtual function table provides the function that the compiler actually calls. A virtual function table is actually a virtual function address that is stored for declaring a class object. When we create a class object, the compiler automatically generates a pointer *__vptr (a hidden pointer) that points to the Address table of all the virtual functions in the class. (In fact, a virtual function table is a table of function address arrays.) Note that, unlike the *__vptr and *this pointers, *this is a function parameter that is used by the compiler to resolve a self-reference, and *__vptr is a true pointer. each class, whether it is a base class or a subclass, has its own virtual table, and *__vptr is inherited. let's look at one more example: Example:

#include <iostream>
using namespace std;

class A
{
    public:
     virtual void f()   { cout << "A’s f()" << endl; } //f()被声明为虚函数
      virtual void g()   { cout << "A’s g()"<< endl; } //g()被声明为虚函数 

};

Class B:public A
{
Public
void F () {cout << "B ' s F ()" << Endl;}
};

Class C:public A
{
Public
void G () {cout << "C ' s G ()" << Endl;}
};
int main (void)
{
A *pa;
b b;
c C;

PA = &b;
PA-F ();
PA-G ();
PA = &c;
PA-F ();
PA-G ();

return 0;
}

run Result:

b ' F ( )
A ' s f ( )

This program can reflect how virtual functions are implemented by virtual table, and draw a picture of themselves: should be able to clearly reflect the situation (draw on learncpp.com)     1, C + + implementation of polymorphic methods

In fact, many people know that virtual function in C + + implementation mechanism is to use virtual table and virtual pointer, but how exactly? From more effecive C + + one of the articles can be known: is each class with a virtual table, each class of objects with a virtual pointer. The specific usage is as follows:

Class A
{
Public
virtual void f ();
virtual void g ();
Private
int a
};

Class B:public A
{
Public
void G ();
Private
int b;
};

The implementation of a, B is omitted

Because A has virtual void f (), and G (), the compiler prepares a virtual table Vtablea for Class A, which reads as follows:

A::f's address
A::g's address

b because it inherits a, the compiler also prepares a virtual table Vtableb for B, which reads as follows:

A::f's address
B::g's address

Note: Because B::g is rewritten, the g of the virtual table of B puts the entry address of the b::g, but F is inherited from the above, so the address of F is the entry address of the a::f.

And then somewhere there is a statement B BB; When the compiler allocates space, except for the int A, B, and the member of the A, a virtual pointer vptr is assigned, and the layout of the virtual table Vtableb,bb to B is as follows:

Vptr: Virtual table pointing to B Vtableb
int A: Inherits the members of a
int B:B Member

When the following statement:
A *pa = &bB;

The PA structure is the layout of a (meaning that only the first two of the BB objects can be accessed with PA, access to the third item int b)

So in Pa->g (), the compiler knows that G is a member function declared as virtual, and that its entry address is placed in the 2nd item of the table (either the Vtalbea table or the Vtalbeb table), then the compiler compiles the statement as if it were converted: Call * (pa- &GT;VPTR) [1] (the array index of the C language starts from 0 ha ~).

This is the B::G () entry address, then the polymorphism is implemented. (Note that BB's vptr points to the virtual table of B Vtableb)

It is also important to note that, as the implementation is not unique, the C + + standard only requires the use of this mechanism to achieve polymorphism, as to the virtual pointer vptr exactly where an object layout, the standard is not required, each compiler decided by itself. My results are based on g++ 4.3.4 after disassembly and analysis. Reference: Http://blog.chinaunix.net/uid-24178783-id-370328.html http://blog.csdn.net/jiangnanyouzi/article/details/3720807

virtual function Implementation Mechanism

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.