1. How to Implement polymorphism in C ++
In fact, many people know that the implementation mechanism of virtual functions in C ++ is to use virtual tables and virtual pointers. But what is it? From an article in more than Ive C ++, we can know that each class uses a virtual table and each class object uses a virtual pointer. The specific usage is as follows:
Class
{
Public:
Virtual void F ();
Virtual void g ();
PRIVATE:
Int
};
Class B: public
{
Public:
Void g ();
PRIVATE:
Int B;
};
// Implementation of A and B is omitted
Because a has virtual void F (), and g (), the compiler has prepared a virtual table vtablea for Class A. The content is as follows:
| A: Address of F |
| A: Address of G |
Because B inherits a, the compiler also prepares a virtual table vtableb for B. The content is as follows:
| A: Address of F |
| B: Address of G |
Note: Because B: G is rewritten, the G of the virtual table B is placed with the entry address of B: G, but F is inherited from, therefore, the F address is the entry address of a: f.
Then there is a statement B bb somewhere. When the compiler allocates space, in addition to the int A and B member int B of A, it also allocates a virtual pointer vptr, point to the virtual table vtableb of Table B. The BB layout is as follows:
| Vptr: virtual table vtableb pointing to B |
| Int A: inherits members of. |
| Int B: B Member |
When the following statement is used:
A * pA = & BB;
The structure of PA is the layout of a (that is to say, PA can only access the first two items of the BB object, but cannot access the third int B)
In pa-> G (), the compiler knows that G is a member function declared as virtual, and its entry address is placed in a table (whether it is a vtalbea table or a vtalbeb table) for example, call * (Pa-> vptr) [1] (the array index of C language starts from 0 ~).
This item places the entry address of B: G () to realize polymorphism. (Note that the vptr of BB points to the virtual table vtableb of B)
Note that the above implementation is not unique. The C ++ standard only requires the use of this mechanism to implement polymorphism. Where is the virtual pointer vptr placed in an object layout, there is no requirement for the standard, and each compiler decides on its own. The above results are analyzed by disassembly Based on G ++ 4.3.4.
2. Two polymorphism implementation mechanisms and their advantages and disadvantages
In addition to the implementation mechanism of the C ++ polymorphism, there is also an implementation mechanism, which is also a Table query, but by name Table query, is the implementation mechanism of smalltalk and other languages. The advantages and disadvantages of the two methods are as follows:
(1) Check the table by absolute position. This method has completed the index and table items (call * (Pa-> vptr [1]) above) in the compilation phase. therefore, the running speed is relatively fast. The disadvantage is that when a has more virtual members (such as 1000) and B has fewer rewrite members (such as 2, the remaining 998 table items in vtableb of B are pointers to the virtual member functions in A. If the derived system is large, a lot of space is wasted.
For example, the GUI library, taking the MFC Library as an example, has many classes and is an inheritance system. In many cases, only one or two member functions of each class need to be rewritten in the derived class, if the virtual function mechanism of C ++ is used, each class has a virtual table with a large number of duplicates in each table, resulting in low space utilization. Therefore, the message ing mechanism of MFC does not need virtual functions, but the second method is used to realize polymorphism, that is:
(2) look up the table by function name. This solution can avoid the above problem. However, to compare the names, it is sometimes necessary to traverse all the inheritance structures, and the time efficiency is not very high. (For the implementation of message ing in MFC, see the next article)
3. Summary:
If there are not many virtual members of the base class of the inheritance system, and most of the elements to be rewritten in the derived class, it is better to use the virtual function mechanism of C ++;
However, if there are many virtual members of the base class of the inheritance system, or the inheritance system is relatively large, and there are only a few elements in the derived class that need to be rewritten, use the name to search for the table, this is more efficient, and many GUI Libraries, such as MFC and QT
PS. in fact, since the emergence of computers, time and space have become an eternal topic, because they cannot be coordinated in 98% cases; this is the fundamental bottleneck in computer science. The development of software science and algorithms depends on whether it can break through the balance between time and space. Haha
How come computer science and the whole universe? The most basic mysteries of the universe are time and space ~