Polymorphic
Polymorphism refers to the use of the same function name to access the different implementation methods of the function, can be summarized as "one interface, many methods."
C + + supports compile-time polymorphism (also called static polymorphism) and run-time polymorphism (also called dynamic polymorphism), operator overloading and function overloading are compile-time polymorphism, while derived classes and virtual functions implement run-time polymorphism.
The real difference between static polymorphism and dynamic polymorphism is whether the function address is early binding or late binding. If a function is called, the call address of the function can be determined during compiler compilation, and production code is static polymorphic (compile-time polymorphic), which means that the address is early bound. If the address of a function call cannot be determined during the compiler, it needs to be determined at run time, which is late binding, which is dynamic polymorphism (runtime polymorphism).
Here, we are exploring dynamic polymorphism.
C + + Dynamic polymorphism is implemented by virtual functions that allow subclasses (derived classes) to redefine the parent class (base class) member functions, whereas subclasses (derived classes) redefine the parent class (base class) virtual function as overwrite (override), or as override.
The most common usage is the parent class (base class) pointer, which can point to any subclass (derived Class) object (instance), and then invoke the member function of the actual derived class through a pointer to the base class, as shown in the following example:
#include <iostream>using namespace std; class Base { public: void f (int x) { cout << "base::f (int) " << x << endl; } void f (float x) { cout << " Base::f (float) " << x << endl; } // must have a virtual keyword, This is a virtual function virtual void g (void) { cout << "base::g (void)" << endl;} }; class derive: public base { public: // virtual keywords , optional, this is a virtual function virtual void g (void) { cout << "derived::g (void)" << endl;} }; int main (void) { derive d; base *pb = &d; pb->f (; // ) operation result: Base::f (int) 42 pb->f (3.14f); // operation result: base::f (float) 3.14 pb->g (); // Run result: derived::g (void) return 0;}
virtual function table
virtual functions (virtual function) in C + + are implemented by a virtual function table (virtual table), referred to as v-table. Each class containing a virtual function has a table of virtual functions, each of which is the address of a virtual function, that is, each item of a virtual function table is a pointer to a virtual function. C + + classes that do not have virtual functions do not have virtual function tables.
#include <iostream>using namespace std; Class Base {public:virtual void F () {cout << "base::f" << Endl;} virtual void G () {cout << "base::g "<< Endl;} virtual void H () {cout << "base::h" << Endl;}}; int main (void) {Base B; B.f (); "Base::f" B.G (); "Base::g" b.h (); "Base::h" return 0;
The virtual function table for the instance of base (that is, Object B) is as follows:
Note: In the above figure, the virtual function table adds a node, which is the end node of the virtual function table, just like the string Terminator "", which marks the end of the virtual function table. The value of this end flag is different under different compilers.
virtual function table with no virtual function overlay
Next, let's look at what the virtual function table looks like when inheriting.
Suppose you have an inheritance relationship that looks like this:
#include <iostream>using namespace std; class Base {public: Virtual void f () { cout << "Base::f" << endl; } virtual void g () { cout << "Base::g" &NBSP;<<&NBSP;ENDL;&NBSP;} virtual void h () { cout << "Base::h" << &NBSP;ENDL;&NBSP;}&NBSP;};CLASS&NBSP;DERIVE:PUBLIC&NBSP;BASE{PUBLIC:&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;F1 () { cout << "Derive::f1" << endl; } virtual void &NBSP;G1 () { cout << "DERIVE::G1" << endl; } virtual &NBSP;VOID&NBSP;H1 () { cout << "DERIVE::H1" << endl; } };int main (void) { derive d; //derived class object return 0;}
Note that in this inheritance relationship, subclasses do not overload functions of any parent class. So, in an instance of a derived class (Derive D), its virtual function table looks like this:
The virtual function table with no virtual function overrides is characterized as follows:
1) Virtual functions are placed in the table in the order in which they are declared.
2) The virtual function of the parent class (The derived class) precedes the virtual function of the child class (the base class).
Virtual function table with virtual function overlay
It is meaningless not to overwrite the virtual function of the parent class. The main purpose of the story is to give a comparison. In comparison, we can know more clearly the specific implementation of its internal.
Now, let's take a look at what it would look like if there were virtual functions in the subclass that overloaded the parent class.
#include <iostream>using namespace std; class Base {public: Virtual void f () { cout << "Base::f" << endl; } virtual void g () { cout << "Base::g" << Endl; } virtual void h () { cout << "Base::h" << endl; } };class derive:public base{public: //overriding the F () virtual function of a parent class virtual void f () { cout << "Derive::f" << &NBSP;ENDL;&NBSP;}&NBSP;&NBSP;&NBSP;VIRTUAL&NBSP;VOID&NBSP;G1 () { cout << "Derive:: G1 " << endl; } virtual void h1 () { cout < < "Derive::h1" << endl; } };int main (void) { base *p = null; //Parent class Pointer base b; //Parent object derive d; //Sub-category objects p = &b; //the parent class pointer to the parent class object p->f (); //run Result: "Base::f" p = &d; //the parent class pointer to the subclass object p->f (); //Run Result: "Derive::f" return 0;}
In order to let you see the effect after the inheritance, in the design of this class, only a virtual function of the parent class is overwritten: F (). Then, for instances of derived classes, the virtual function table will look like this:
The virtual function table with virtual function overrides is characterized as follows:
1) the covered F () function is placed in the location of the original parent virtual function in the virtual table.
2) functions that are not covered are still.
In this example:
Base *p = NULL; Parent class pointer
p = &d; Parent class pointer to child class object
P->f (); Run Result: "Derive::f"
The position of the F () of the parent virtual function table in memory referred to by P (that is &d) has been superseded by the actual subclass Derive::f () function address, so Derive::f () is called when the actual call occurs. This enables polymorphism.
For more examples, please click this link: http://blog.csdn.net/tennysonsky/article/details/8264255
This tutorial sample code download Please click this link: Http://download.csdn.net/detail/tennysonsky
This article transferred from: Http://blog.csdn.net/haoel
Copyright NOTICE: This blog post, mostly I compiled, or in the network collection, reproduced please indicate the source!!
Introduction to C + + Introductory learning--virtual function table