Virtual functions in C + + (virtual function)

Source: Internet
Author: User
Tags function definition object model
Virtual functions (virtual function) Favorites in C + + turn from: http://blog.csdn.net/lengxingfei/archive/2007/11/09/1876570.aspx I. 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. Suppose 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;}}; Then, when used, 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 the following code is a virtual function, 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 () called} 1.1 polymorphism

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 methods used are more complex: void Bar (A * a) {A->foo ();//called A::foo () or B::foo (). Because Foo () is a virtual function, so in the bar this function, only based on this code, it is not possible to determine whether the call is A::foo () or B::foo (), but it is certain that if a is pointing to an instance of Class A, then A::foo () is invoked, If a refers to an instance of Class B, then 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, for example in 1.1: void Bar (A * a) {A->foo ();} will be overwritten 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'm going to make it clear: 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.

Two. The syntax of virtual functions three. Virtual function Use skill3.1 Private virtual function attached: virtual function and pure virtual function usage in C + + 1. Virtual functions and pure virtual functions can be defined in the same class (class), classes containing pure virtual functions are called abstract classes, Classes, which contain only virtual functions, cannot be called abstract classes. 2. Virtual functions can be used directly, you can also invoke a quilt class (sub Class) overload later in polymorphic form, whereas a pure virtual function must be implemented in a subclass (sub Class) to be used, because pure virtual functions are declared and undefined in the base class. 3. Virtual functions and pure virtual functions can be overloaded in subclasses (sub Class) and invoked in polymorphic form. 4. Virtual functions and pure virtual functions often exist in abstract base classes (abstract base class-abc), inherited subclass overloads, to provide a unified interface. 5. Virtual function definition form: Virtual {method body}; Pure virtual function definition form: virtual {} = 0; There cannot be a static identifier in the definition of a virtual function and a pure virtual function, for the simple reason that a function that is modified by static requires bind at compile time, whereas a virtual function is dynamically bound (run-time bind) and is decorated with a function lifecycle (life Recycle) is not the same. 6. If a class contains a pure virtual function, any statement that attempts to instantiate the class will cause the error to occur because the abstract base class (ABC) cannot be invoked directly. A method that calls its subclasses after a quilt class inherits the overload. The following is a simple virtual function and the use of pure virtual cold number demo, the purpose is to give a brief. #include//father class class Virtualbase {public:virtual void Demon () = 0;//prue virtual function virtual void Base () { cout<< "This is farther class" <}; Sub Class class Subvirtual:p ublic virtualbase {public:void Demon () {cout<< "This is subvirtual!" < void base () {cout<< "This is subclass base" <}; /* InstanCe class and sample/void Main () {virtualbase* inst = new Subvirtual ();//multstate pointer Inst->demon (); inst-> Base (); Inst = new Virtualbase (); Inst->base () return; }

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 Flags A virtual function is a 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 example, 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.

Consider the following example: Class A {public:void foo () {bar ();} private:virtual void Bar () {...}}}; Class B:public A {private:virtual void bar () {...}}; In this example, although bar () is private in Class A, it can still appear in derived classes and can still produce polymorphic effects like public or protected virtual functions. It does not happen because it is private, a::foo () cannot access B::bar (), nor does B::bar () have any effect on the override of A::bar (). The meaning of this writing is: A tells B that you'd better override my bar () function, but you don't care how it is used, and don't call this function yourself. 3.2 virtual function calls in constructors and destructors

When a virtual function of a class is invoked in its own constructors and destructors, they become normal functions and are not "virtual". That is, you cannot make yourself "polymorphic" in constructors and destructors. For example: Class A {public:a () {foo ();}//Here, A::foo () is invoked anyway. ~a () {foo ();}//Ibid. virtual void foo (); }; Class B:public A {public:virtual void foo ();}; void Bar () {A * a = new B; Delete A;} If you want to delete a, cause b::foo () to be invoked, you are wrong. Similarly, at new B, the constructor of a is invoked, but in the constructor of a, the call is A::foo () instead of B::foo (). Virtual functions in more than 3.3 inheritance 3.4 when to use virtual functions

When you design a base class, if you find that a function needs to behave differently in a derived class, it should be virtual. From a design point of view, a virtual function appearing in a base class is an interface, and a virtual function appearing in a derived class is a concrete implementation of the interface. By using this method, you can abstract the behavior of an object. Take the factory method pattern in design mode [2] As an example, creator's FactoryMethod () is a virtual function, and the derived class override the function to produce a different product class, The resulting product class is used by the anoperation () function of the base class. The Anoperation () function of the base class operates on the product class, and of course the product class must also have polymorphic (virtual functions). Another example is set operations, assuming that you have a class hierarchy with a Class A base class and a std::vector to hold an instance pointer that is not the same in the class hierarchy, then you will want to manipulate the class in this collection Instead of returning each pointer to its original type (derived class), you want to do the same for them. Then you should declare this "same action" as virtual. In reality, this is far more than the two examples I've given, but the big principle is that "if you find a function that needs to behave differently in a derived class, then it should be virtual". This sentence can also be reversed: "If you find that the base class provides a virtual function, then you'd better override it."

Related Article

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.