Virtual functions.

Source: Internet
Author: User

Number of empty letters

When talking about a person as the master, it is usually said that his ears are soft. When people say something, they forget the original one. When others say that they are going east, they will go east. When someone says they are going west, he will be back immediately. But the benefit is obvious. This person is very obedient. If you sometimes don't know what you want to do, or you are not sure what you want to do later, ask him to wait. When you decide what you want, tell him what you want and let him do it. In reality, such a thing is not uncommon. The secretary needs to record, write a report, arrange a schedule, contact the customer, and so on. These jobs are all done at your instructions. It would be nice to have such obedient code during programming. Of course this is not a dream, and it can be fully implemented.

When solving an equation, there is an unknown concept. A symbol that can be any number represents a number that does not know the value temporarily, and then the expected value is obtained through the calculation rules, from the programming point of view, we add an indirect layer. We do not process a value for the time being, but rather a symbol related to the value. If the value is changed, it is the corresponding attribute, we can use member variables for processing. What if the change is an operational rule? Y = f (x), this f (x) is variable, so we need to make our solutions generic to various possible f (x ), then we need to provide an indirect layer to connect different functions. In C ++, we can use function pointers.

The function of a pointer is to save the position of a certain type of object in the memory. Changing the pointer value allows it to point to different objects. (The pointer itself is also a type)

How does the compiler determine the code of the called function at runtime for a virtual function? That is to say, how is a virtual function actually processed by the compiler? Here we will briefly introduce the "standard" method.

The "standard" mode is the so-called "vtable" mechanism. The compiler creates a virtual function table for a function declared as virtual in a class.Vtable. Vtable is actually an array of function pointers. Each virtual function occupies a position in this array. A class has only one vtable, no matter how many instances it has. The derived class has its own vtable, but the vtable of the derived class has the same function arrangement sequence as the vtable of the base class. virtual functions with the same name are placed in the same position of two arrays. When creating a class instance (object), the compiler also addsVptr field (virtual function table pointer)This field points to the vtable of this class. Through these methods, the compiler will rewrite this call when it sees a virtual function call, as shown in the following example:

Class
{
Public:
Virtual void Foo () {cout <"A: Foo () is called" <Endl ;}
};

Class B: public
{
Public:
Virtual void Foo () {cout <"B: Foo () is called" <Endl ;}
};

In this case, we can:

A * A = new B ();
A-> Foo (); // here, although a points to a, the called function (FOO) is B!

Void bar (A *)
{
A-> Foo (); // is a: Foo () or B: Foo () called ()?
}
Because Foo () is a virtual function, in bar function, only according to this Code, it cannot be determined whether a: Foo () or B: is called here :: foo (), but it is certain that if a points to an instance of Class A, A: Foo () is called. If a points to an instance of Class B, then B: Foo () is called.

During compilation, the bar function will be rewritten:

Void bar (A *)
{
(A-> vptr [1]) ();
}

Because the derived class and the Foo () function of the base class have the same vtable index, and their vptr points to different vtables, this method can be used to determine which Foo () to call at runtime () function.

Although the actual situation is far from that simple, the basic principle is roughly the same. Shows the object model of Class X:

The polymorphism of virtual functions can only be achieved through object pointers or reference calls of objects, as shown in the following calls:
 

     
      X obj;X* ptr = &obj; X& ref = obj;ptr->VirtualFunc();ref.VirtualFunc();
     

Converts the C ++ compiler to the following form.
 

     
      ( *ptr->vptr[2] )(ptr);( *ptr->vptr[2] )(&ref);
     

2 indicates that virtualfunc has 2nd slots in the class's virtual function table. Therefore, in C ++, use function pointers to implement virtual functions,The compiler hides a function pointer array in the class (because many member functions may be called virtual function tables). Obviously, a step is added to search for the function location. Therefore,Using Virtual functions reduces execution efficiency, You need to choose between efficiency and flexibility. The call of a virtual function is equivalent to a function pointer call of C, and its efficiency is not much reduced.

Let's use C ++ to look at the effects of virtual functions.

# Include <iostream>

# Include <stdlib. h>

Class normala {

Public:

Void dosomething (void) {cout <"This is class normala." <Endl ;}

};

Class normalb: Public normala {

Public:

Void dosomething (void) {cout <"This is class normalb." <Endl ;}

};

Class normalc: Public normalb {

Public:

Void dosomething (void) {cout <"This is class normalc." <Endl ;}

};

 

Class virtuala {

Public:

Virtual void dosomething (void) {cout <"This is class virtuala." <Endl ;}

};

Class implements ALB: Public implements Ala {

Public:

Void dosomething (void) {cout <"This is class implements Alb." <Endl ;}

};

Class extends ALB: Public extends ALB {

Public:

Void dosomething (void) {cout <"This is class should..." <Endl ;}

};

Int main ()

{

Normala NA;

Normalb NB;

Normalc NC;

Virtuala Va;

Virtualb Vb;

Virtu1c VC;

Normala * PNA;

Virtuala * PVA;

Na. dosomething ();

NB. dosomething ();

NC. dosomething ();

 

Va. dosomething ();

VB. dosomething ();

VC. dosomething ();

 

PNA = & NA;

PNA-> dosomething ();

PNA = & nb;

PNA-> dosomething ();

PNA = & NC;

PNA-> dosomething ();

 

PVA = & Va;

PVA-> dosomething ();

PVA = & VB;

PVA-> dosomething ();

PVA = & VC;

PVA-> dosomething ();

Cin. Get ();

Return 0;

}

The result is

This is class normala. // call normala: dosomething ();

This is class normalb. // call normalb: dosomething ();

This is class normalc. // call normalc: dosomething ();

This is class virtuala. // call virtuala: dosomething ();

This is class virtualb. // call virtualb: dosomething ();

This is class should... // The Calling method is: dosomething ();

This is class normala. // call normala: dosomething (); no virtual function table, normala * specifies the type

This is class normala. // call normala: dosomething (); no virtual function table, normala * specifies the type

This is class normala. // call normala: dosomething (); no virtual function table, normala * specifies the type

This is class virtuala. // call virtuala: dosomething (); the virtual function table Pointer Points to virtuala.

This is class virtualb. // call virtualb: dosomething (); the virtual function table Pointer Points to virtualb.

This is class virtushortname. // The Calling method is: dosomething (). The pointer to the virtual function table points to the virtualb.

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.