Virtual function in C ++ (Virtual Function)

xiaoxiao2021-03-06  86

C virtual functions (virtual function) subtitle: Author: Unknown Source: Unknown C virtual functions (virtual function) 1. Introduction to C virtual functions mechanism for implementing polymorphism (polymorphism) of. The core concept is to access the functionality defined by the base class. Suppose we have the following class level: class a {public: virtual void foo () {cout << "A :: foo () is called << endl;}}; class b: public a {public: virtual void foo () {cout << "B :: foo () is caled << Endl;}}; then, when you are using, we can: a * a = new b (); A-> foo (); / / Here, Although a pointer to A, the called function (foo) is B! This example is a typical application of the virtual function. In this example, you may have some concepts for virtual functions. It is virtual in the so-called "delayed" or "dynamic cable", and the call of a class function is not determined at the compilation time, but is determined at runtime. Since the code is written, it cannot be determined that the function of the base class is still the function of which is the "virtual" function. The virtual function can only reach the polymorphic effect by means of a pointer or reference, if it is the following code, although it is a virtual function, it is not a 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 virtual functions, It is easy to consider what is polymorphism. Still against the above level, but the method used by the method is more complicated: void bar (a * a) {a-> foo (); // called A :: foo () or b :: foo ( )? } Because foo () is a virtual function, in this function, only according to this code, there is no determination here to be called A :: foo () or b :: foo (), but can be sure: if a pointing to an example of a class, then A :: foo () is called, if a point to the Class B instance, then b :: foo () is called. This same code can produce different effects, known as "polymorphism". 1.2 What is the use of polymorphism? Multi-state is so magical, but what can be used? This proposition, I am difficult to use one or two sentences, the general C tutorial (or other object-oriented tutorial) use a picture example to display polymorphism purposes, I will no longer repeat this example, if you don't know This example, it should be introduced if you find this book. I tried to describe an example of an abstract angle, and then combined with the example of the drawing, maybe you are more likely to understand. In the object-oriented programming, the data is first abstract (determined the base class) and inheritance (determined to send class), and constitute a class level. This class-level user is using them, if you still write the code for the base class when you need the base class, you will be able to write the code for the classification when you need to derive class, it is equals that the class level is completely exposed to the user. .

If this class hierarchy changes (add new classes), you need to "know" (for new classes). This increases the coupling between the class level and its users, and some people are listed as one of the "Bad Smell" in the program. Polymorphisms can make programmers from this dilemma. Take a look at the example of 1.1, bar () as a class-level user of AB, it doesn't know how many classes in this class level, every class is called, but it can work well, when After a C class is born from the A class, BAR () does not need to "know" (modify). This is completely attributed to the polymorphic-compiler to generate code that can determine the modified function at runtime. 1.3 How to "Dynamic Board" compiler How to generate the code that is called function for the virtual function to determine the code of the modified function? That is, how is the virtual function actually processed by the compiler? Lippman speaking several ways in depth exploration of the different chapters in the C object model [1], here is the "standard" method briefly introduces it. What I said "Standard" is the so-called "vTable" mechanism. The compiler found a function that is declared as Virtual in a class, which will make a virtual function table, which is VTABLE. VTable is actually an array of function pointers, each virtual function, which takes up a slot of this array. A class has only one vTable, regardless of how many instances it. Detecting classes have their own vTable, but the VTABLE of the derived class has the same functionality in the same function as the base class, and the virtual function of the same name is placed in the same location of the two arrays. When you create a class instance, the compiler also adds a VPTR field in the memory layout of each instance, which points to the VTABLE of this class. Through these means, the compiler will rewrite this call when seeing a virtual function call, for 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 () function of the derived class and base class has the same VTable index, and their VPTR points to different vTable, so through Such methods can determine which FOO () function that is called at runtime. Although the actual situation is far less simple, the basic principle is rough. 1.4 OverLoad and Override virtual functions are always rewritten in the derived class, which is called "override". I often confuse two words "Overload" and "Override". But with more and more books of various C , the later programmers may not commit the mistake I have committed. But I intend to clarify: Override is a virtual function that assigns the student rewriting base class, which is like a Foo () function in the Class A in the front B class. The rewritten function must have a consistent parameter table and return value (the C standard allows the return value to the case, this I will introduce some of the "Syntax" section, but few compilers support this feature). This word seems to have no suitable Chinese words, and some people are translated into "coverage" and is also appropriate. The OverLoad appointment is translated into "overload". It means that a function of writing a different function with the existing function but the parameter table. For example, a function can accept an integer as a parameter, or the floating point number can be accepted as a parameter. 2. The symbol of the syntax virtual function of the virtual function is the "Virtual" keyword.

2.1 Use the Virtual keyword to consider the following class level: Class a {public: Virtual void foo ();}; class b: public a {public: void foo (); // no virtual keyword!}; Class C: public B // Inherit from B, not inherited from A! {public: void foo (); // no virtual keyword! }; In this case, B :: foo () is a virtual function, C :: foo () is also virtual function. Therefore, it can be said that the base class declands the virtual function, in the derived class is also a virtual function, even if the Virtual keyword is no longer used. 2.2 Pure virtual functions The following statement indicates a function as a pure virtual function: Class A {public: Virtual void foo () = 0; // = 0 logo a virtual function is a pure virtual function}; a function declaration is pure, pure The virtual function means: I am an abstract class! Don't install me! The pure virtual function is used to standardize the behavior of derived classes. It is actually the so-called "interface". It tells the user, and my derived class will have this function. 2.3 The false argument function of the function can be virtual, even pure. For example: Class A {public: Virtual ~ a () = 0; // Pure Patient Activity}; 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-false argument function 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 In this example, the program may not run like you imagine, when executing Delete A, actually only A :: ~ a () is called, and the destructor Class B is Not called! Is this terrible? If you will be changed to Virtual, you can guarantee that B :: ~ b () is also called when Delete A is. Therefore, the sectors of the base class must be Virtual. There is no role in the destructor of pure virtuality, it is a virtual. Usually only when you want to turn a class into an abstract class (categories that cannot be instantiated), and this class does not have the right function can be purely ficted, you can use the pure destructor to achieve the purpose. 2.4 fictional creation function? The constructor cannot be empty. 3. Virtual function uses skills 3.1 Private virtual function 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 the A class, it can still appear in the derived class and can still be virtual with public or protected The function is like a polymorphic effect.

转载请注明原文地址:https://www.9cbs.com/read-94533.html

New Post(0)