C ++ FAQ Lite [20] - inheritance (virtual function) (update)

zhaozj2021-02-08  275

[20] Inherited - Virtual Function (Part of C FAQ Lite, Copyright © 1991-2001, Marshall Cline, Cline@parashift.com)

体,, nicrosoft @ sunistudio.com (East day production room, East day document)

FAQS in section [20]:

[20.1] What is "virtual member function"? [20.2] How does C achieve dynamic binding and static types? [20.3] What is the difference between the virtual member function and the non-virtual member function call mode? [20.4] When is the destructor? [20.5] What is "Virtual Constructor"?

[20.1] What is "virtual member function"?

From the object-oriented point of view, it is the most important feature of C : [6.8], [6.9].

The virtual function allows the implementation of the derived class replacement base class. The compiler ensures that the object is always called when the object is derived, and the implementation of the derived class is always called. This allows the algorithm of the base class to be derived, even if the user does not know the details of the derived class.

Detective classes can completely replace the basic class member function (override) or partially replace the base class member function (increase). If you prefer, the latter is completed by the sending class member function to call the base class member function.

[TOP | BOTTOM | Previous Section | Next Section]

[20.2] How does C achieve dynamic binding and static types?

When you have an object's pointer, the object is actually a derived class of the pointer type (for example: a VEHICLE * pointer actually points to a Car object). There are thereafter, there are two types: pointers (static) types (this is Verhi), and the (dynamic) type (Dynamic) type pointing to the object (which is car).

The static type means that the legality of the member function call is as early as possible: the compiler is compiled. The static type of the compiler determines whether the member function call is legal. If the pointer type can handle the member function, the pointer refers to the object of course to handle it very well. For example, if a VEHICLE has a member function, since Car is a Vehicle, then CAR is of course the member function.

Dynamic Binding means that the code address called the member function call is determined in the final time: the dynamic type of object based on the runtime. Because the process of binding to the actual call is dynamically completed (at runtime), it is called "dynamic binding". Dynamic binding is one of the results caused by virtual functions.

[TOP | BOTTOM | Previous Section | Next Section]

[20.3] What is the difference between the virtual member function and the non-virtual member function call mode?

The non-virtual member function is static. That is, the member function (at compile time) is static, the selection is based on the type of pointer (or reference) of an object object.

In contrast, the virtual member function is dynamically determined (at runtime). That is, the member function (at runtime) is dynamically selected, the selection is based on the type of object, rather than pointing to the type of pointer / reference. This is called "dynamic binding". Most compilers use some of the following techniques: If the object has one or more virtual functions, the compiler places a hidden pointer into the object, the pointer is called "Virtual-Pointor" or "V-Pointer". This V-Pointer points to a global table that is called "virtual-Table" or "V-Table". The compiler creates a V-Table for each class containing at least one virtual function. For example, if the Cirle class has virtual functions DDRAW (), Move (), and resize (), there is only one V-Table related to the CRICLE class, even with a large pile of Circle objects. And the V-Poiner of each Circle object will point to Circle's V-Table. This V-Table has a pointer to each virtual function that points to the class. For example, Circle's V-Table will have three pointers: a pointing Circle :: DRAW (), a pointing Circle :: Move (), and a pointing Circle :: Resize (). When distributing a virtual function, the runtime system follows the V-Pointer of the object to find the class of V-Table, then follow the appropriate items of the appropriate item in V-Table. The space overhead of the above technology is present: an additional pointer per object (only for objects that require dynamic binding), plus an additional pointer for each method (for the virtual method only). Time overhead is also: and normal function call comparison, the virtual function call requires two additional steps (get the value of the V-POIinter, the address of the method). Since the compiler is compiled, the non-virtual function is solved by the pointer type, so these overhead does not occur on the non-virtual function. Note: Since there is no content such as inheritance, virtual inheritance, RTTI and other content, there is no content such as the content / time theory of the function of the function, and the above discussion is quite simple. If you want to know other content, please ask Comp.lang.c ; don't send me E-mail! [TOP | BOTTOM | Previous Section | Next Section]

[20.4] When is the destructor?

When you may delete the derived class object via the base class pointer.

The virtual function is bound to the code of the class of the object, not the classes / references. If the base class has a false arrangement function, the DELETE BASEPTR (the translation: ie the base class pointer), the destructor of the object type of the Baseptr is called, not the destructor of the type of the pointer. This is usually a good thing.

Techno-Geek Warning; PUT Your Propeller Hat on. From the technical point, if you plan to allow other people to call the dominant destructor's destructor's destructor (by DELETE, it is normal), and the destructed object is The object of derived class of important destructive functions, you need to make the analyte function of the base class be virtual. If a class has an explicit destructor, or there is a member object, the member object or base class has an important destructor, then this class has an important destructor. (Note This is a recursive definition (for example, a class with an important destructuring function, it has a member object (it has a base class (the base class has a member object (it has a base class (this base class is explicit) Destructor)))))))))))))))))))))))))) End Techno-Geek Warning; Remove Your Propeller Hat If you have difficulty understanding the above rules, try this simple: Class should have a false prevention function, unless this class has no virtual functions . Principle: If there is a virtual function, you want to use the derived object through the base class pointer, and you may have something you may do, you may contain a call destructor (usually hidden through the delete). Once you add a virtual function in the class, you already need to pay space costs for each object (a pointer to each object; pay attention to this is theoretical compiler characteristic; actually every compiler is doing this So this is usually not an additional to the destructive function.

[TOP | BOTTOM | Previous Section | Next Section]

[20.5] What is "Virtual Constructor"?

A usage that allows you to do some C not directly supporting.

You may get the effect of the fiction function generated by virtual function Virtual Clone () (for copy constructor) or virtual function Virtual Create () (for the default constructor).

Class Shape {public: virtual ~ shape () {}

// Vocabulary function

Virtual void Draw () = 0;

// Pure virtual function

Virtual void move () = 0;

// ...

Virtual Shape * Clone () const = 0;

// Use a copy constructor

Virtual Shape * Create () const = 0;

// Use the default constructor

}; Class Circle: Public Shape {public: Circle * Clone () const {return new circle (* this);} circle * create () const {return new circle ();

// ...

}

In a Clone () member function, the code new circle (* this) calls the Circle's copy constructor to copy the status of this to the new Circle object. In the Create () member function, the code new circle () calls the default constructor of the Circle. Users will use them as "fictional creation functions":

Void Usercode (Shape & S) {Shape * S2 = S.Clone (); Shape * S3 = S.CREATE ();

// ...

Delete S2;

/ / Here, you may need a false argument function

delete s3;

This function will work correctly, regardless of Shape is a Circle, Square, or other types of Shape, or even they do not exist.

Note: The return value type of member function CIRCLE's Clone () is deliberately different from the member function shape's clone (). This feature is called "Return of Candarings", which is not part of the language. If your compiler is not allowed to declare Circle * Clone () const (eg, prompt "The Return Type Is Different" or "The Member Function's Type Differse from Type Alone"), Explain that your compiler is old, then you must change the return type as Shape *.

[TOP | BOTTOM | Previous Section | Next Section]

E-mail the author [C FAQ Lite | Table of Contents | Subject Index | About The Author | © | Download Your Own Copy] Revised Apr 8, 2001

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

New Post(0)