The virtual function in the written test--c++ (virtual functions)
Source: Internet
Author: User
Virtual functions in C + + (virtual function)
1. Introduction
Virtual functions are the mechanisms used in C + + to implement polymorphism (polymorphism). The core idea is to access the function defined by the derived class through the base class. Let's say we have the following class hierarchy:
Class A
{
Public
virtual void foo () {cout << "A::foo () is called" << Endl;}
};
Class B:public A
{
Public
virtual void foo () {cout << "B::foo () is called" << Endl;}
};
So, in use, we can:
A * a = new B ();
A->foo (); Here, A is a pointer to a, but the called function (foo) is B!
This example is a typical application of a virtual function, in which case you may have some idea of a virtual function. It is virtual on the so-called "delayed" or "dynamic", the invocation of a class function is not determined at compile time, but is determined at run time. Because it is not possible to write code that is called a function of a base class or a derived class, it becomes a "virtual" function.
A virtual function can only use pointers or references to achieve polymorphic effects, and if it is the following code, it is a virtual function, but it is not polymorphic:
Class A
{
Public
virtual void foo ();
};
Class B:public A
{
virtual void foo ();
};
void Bar ()
{
A A;
A.foo (); A::foo () is called
}
1.1 polymorphic
After understanding the meaning of a virtual function, it is easy to consider what polymorphism is. The class level is still the same, but the method used is a bit more complicated:
void Bar (A * a)
{
A->foo (); Whether the call is A::foo () or B::foo ().
}
Because Foo () is a virtual function, in bar This function, based on this code, it is not possible to determine whether the call here is A::foo () or B::foo (), but it is certain that if a refers to an instance of Class A, then A::foo () is invoked if a refers to an instance of Class B , the B::foo () is invoked.
This same code can produce different effects of the characteristics, known as "polymorphism."
What is the use of 1.2 polymorphism.
Polymorphism is so magical, but it can be used to do what. This proposition I can not use one or two sentence summary, General C + + tutorials (or other object-oriented language tutorials) Use a drawing example to show the use of polymorphic, I will not repeat this example, if you do not know this example, casually find this book should have introduced. I try to describe it from an abstract angle, and then I'll go back to the example of that drawing, and maybe you'll understand it more easily.
In object-oriented programming, the first step is to abstract the data (determine the base class) and inheritance (to determine the derived class) to form the class hierarchy. When users of this class level use them, if they still write code for the base class when they need the base class, writing code for the derived class when a derived class is needed is equal to the class level being completely exposed to the user. If there is any change in this class level (adding a new Class), the user is required to "know" (write code for the new Class). This adds to the coupling between the class hierarchy and its users, which has been listed as one of the "bad smell" in the program.
Polymorphism can leave programmers out of this dilemma. Looking back at the example in 1.1, bar () is the user of this class of a-b, it doesn't know how many classes there are in this class, what each class is called, but it works just as well, and when a C class derives from Class A, bar () does not need to "know" (modify). This is entirely due to polymorphism--the compiler generates code for virtual functions that can determine which functions are called at run time.
1.3 How to "dynamic joint edit"
How does the compiler generate code for virtual functions that can be run at any time to determine which functions are called? In other words, how virtual functions are actually handled by the compiler. Lippman in the Deep exploration of the C + + object model [1] in different chapters in several ways, here the "standard" way to briefly introduce.
What I call the "standard" approach is the so-called "VTABLE" mechanism. The compiler discovers that a class has a function declared as virtual, and it makes a virtual function table, which is vtable. Vtable is actually an array of function pointers, with each virtual function taking up a slot of the 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 order as the vtable of the base class, and the virtual function with the same name is placed in the same position as the two arrays. When you create a class instance, the compiler also adds a vptr field to the memory layout of each instance, which points to the vtable of this class. By these means, when the compiler sees a virtual function call, it overwrites the call to the example in 1.1:
void Bar (A * a)
{
A->foo ();
}
will be rewritten as:
void Bar (A * a)
{
(A->vptr[1]) ();
}
Because the Foo () functions of the derived class and the base class have the same vtable index, and their vptr point to a different vtable, this method allows you to decide which Foo () function to call at run time.
Although the reality is far from so simple, the rationale is generally the same.
1.4 Overload and override
A virtual function is always overwritten in a derived class, which is called "override". I often confuse the two words "overload" and "override". But with all kinds of C + + books becoming more and more, later programmers may not make the same mistakes that I've made. But I would like to clarify:
Override refers to a derived class that overrides a virtual function of a base class, just as the Foo () function in Class A is overridden in our previous Class B. The overridden function must have a consistent parameter table and return value (the C + + standard allows the return value to be different, which I will briefly introduce in the "Syntax" section, but few compilers support this feature). This word seems to have been no suitable Chinese words to correspond, someone translated as "cover", but also more appropriate.
The Overload convention moralize is translated as "overloaded." is to write a function that has the same name as an existing function but has a different parameter table. For example, a function can accept an integer as an argument, or a floating-point number as an argument.
2. The syntax of virtual functions
The symbol for a virtual function is the "virtual" keyword.
2.1 Using the Virtual keyword
Consider the following class hierarchy:
Class A
{
Public
virtual void foo ();
};
Class B:public A
{
Public
void Foo (); No virtual keyword!
};
Class C:public B//inherits from B, not from a.
{
Public
void Foo (); There is no virtual keyword.
};
In this case, the B::foo () is a virtual function, and the C::foo () is also a virtual function. Thus, it can be said that a virtual function declared by a base class is also a virtual function in a derived class, even if the virtual keyword is no longer used.
2.2 Pure virtual functions
The following declaration indicates that a function is a pure virtual function:
Class A
{
Public
virtual void foo () = 0; =0 flag a virtual function as pure virtual function
};
When a function is declared as pure virtual, the pure virtual function means: I am an abstract class. Don't instantiate me. A pure virtual function is used to regulate the behavior of a derived class, which is actually called an "interface". It tells the user that my derived class will have this function.
2.3 Virtual destructor
Destructors can also be virtual, or even pure virtual. For example:
Class A
{
Public
Virtual ~a () = 0; Pure virtual destructor
};
When a class is intended to be used as a base class for other classes, its destructor must be virtual. Consider the following example:
Class A
{
Public
A () {Ptra_ = new char[10];}
~a () {delete[] Ptra_;}//non-virtual destructor
Private
char * PTRA_;
};
Class B:public A
{
Public
B () {ptrb_ = new char[20];}
~b () {delete[] ptrb_;}
Private
char * PTRB_;
};
void Foo ()
{
A * a = new B;
Delete A;
}
In this case, the program may not run as you think, and when you execute delete a, only a::~a () is invoked, and the destructor of Class B is not invoked. Whether this is a bit scary.
If you change the above A::~a () to virtual, you can ensure that the b::~b () is also called at the time of delete a. Therefore, the destructor of the base class must be virtual.
Pure virtual destructor does not have any function, is a virtual enough. It is usually possible to use a pure virtual destructor to achieve an objective only if you want to turn a class into an abstract class (a class that cannot be instantiated), and the class does not have the proper function to be pure-virtual.
2.4 Fictitious creation function.
Constructors cannot be virtual.
3. Virtual function Use Skill 3.1 Private's virtual function
Consider the following example:
Class A
{
Public
void foo () {bar ();}
Private
virtual void Bar () {...}
};
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