Implementation of C + + polymorphism

Source: Internet
Author: User

The magic of C + +

In C + +, through inheritance, subclasses can get the members of the parent class, through polymorphism, C + + can be implemented at run time based on the actual type of object calls the correct virtual function, C + + and C language can not do the overloaded behavior ... How is this magic of C + + implemented?
In fact, C + + is used as a code-generation language, as if a C + + program is written, the C + + preprocessor first translates C + + code into C code, and then the C language compiler generates the executable file. When using inheritance, the subclass gets the members of the parent class, not the magic of C + +, but rather the compiler copies the members of the parent class that can be inherited--copies the code into the subclass declaration--into the subclass, and when the member function is called through the object, the call operation is converted to a non-member function. and add a pointer to the object that invokes the function as an extra parameter, when using overloaded functions, the overloaded function name is modified to a unique name based on the number of parameters, type, constant, static or not, and an object is defined, and the preprocessor writes the constructor that invokes the corresponding class function to the appropriate location. When an object leaves the scope, the destructor is added to the correct location, which causes the constructor to be called automatically as the destructor (which is called automatically, but actually these actions are made by the compiler, not the C + + language has this magical ability) ... Finally C + + program was rewritten as a C language program, but we do not see the C language program just.

Correct use of C + + polymorphic forms

Polymorphism in C + + refers to a call made by a base class pointer or reference to a derived class object to achieve a different operation at run time based on the actual subtype of the object that the base class pointer refers to. Two key points, the first is that the code surface looks like the operating base class, and the runtime operation is determined by the actual type of the pointer's object, and if the derived class pointer is used to point to the base class object it is not the correct use of polymorphism; the second is a pointer or reference that does not make the base class Object "points to" derived class object, which not only does not achieve polymorphic effects, but can also get errors due to object cutting. Why do I have to use the base class pointer to point to the derived class object, and why do we need pointers or references? To answer the second question first.

Why is a pointer or reference

This is because a pointer or reference is a data type that stores memory addresses, in order to store pointers or references, there must be an area in the computer's memory provided to hold pointers or references, usually the size of this chunk is 4byte (32-bit machine), which means "any pointer takes up space" meaning, A value is placed in this 4byte space, which points to another location in memory, and when the computer accesses a pointer to an object, it jumps to that position according to the value stored in the pointer variable, and then interprets the meaning of the data in a certain space after the position, based on the type of the pointer. Each time you define an object, you can only get the address of the defined object itself. Therefore, if you use a base class object that cannot "point" to the derived class object, object can only point to itself (the variable name is translated to the address where the variable is stored, and the computer accesses the variable based on that address). Using pointers or references, depending on the value of the pointer or reference variable, you can find the object that points to, and if you just want to find the object without doing anything else, it doesn't matter what type of object it is, but if you are reading the actual data of the object, you need to know how to interpret the data in that location. Therefore, the derived class object can be found using the base class pointer to the derived class object. But in order to invoke a function that behaves polymorphic in the derived class object, another facility is needed. Yes, virtual table, that's it.

Why is the parent pointer pointing to the child class object

Virtual table is a table placed outside of object, with a pointer to a virtual function in the table vptr, hmm ... The actual implementation also holds a pointer to some information about the class definition itself in the first row of the table, and the typeID function operates on this pointer. Instead of storing only pointers to this table in the object, wouldn't it be a waste of space to put the same table in each object? To further conserve space, do not place vptr in objects that do not require virtual table, how do you determine which classes are needed? Quite simply, the class that declares the virtual function and his subclass are required (the base class has its own table, the subclass has a table of its own, and the vptr in the two classes do not point to the same table)! With virtual table, how to place the function pointer inside, six rules: 1) The table head placed pointer to Type_info, 2) The second place pointer to the virtual destructor, 3) Other virtual functions in the order of declaration in the following table entries; 4) Subclass the same virtual function in the parent class (the overloaded version also corresponds, where the same is not only the same as the function name) where the index of the table entry is the same; 5) The subclass overrides the virtual function of the parent class, then the sub-class rewrite function pointer, if not rewritten, the parent class in the virtual function of the pointer copied over, in the corresponding position; 6) The new virtual functions added by subclasses are placed in the next position in the order of addition of the subclasses, which makes the virtual function table of the subclass and the parent class not as large, and if the subclass does not add a new virtual function, the subclass is as large as the virtual function table of the parent class.
Virtual table is ready, polymorphic can show, a base class pointer to an object, this object may be a base class object, may be derived class A object, or it may be a derived Class B object, which does not matter, just from the space occupied by this object, find Vptr, and then find its index number according to the function name, the index number can find the address of the function to be called, so polymorphism is implemented. This lookup process is performed by the compiler, and the compiler knows the index number of the virtual function in each class, and when it writes down base* pbase = new Someclass,pbase->somevirtualfunc (), the latter statement is converted to pbase-inside the compiler >vptr "Index" (). In this way, the program is not the actual run-time polymorphism, the required behavior is determined in the compilation period, but the original need to do something manually by the C + + preprocessor to do. This explains why a virtual destructor is added to the base class that exhibits polymorphism, and if not, the virtual destructor does not appear in virtual table and is always called when delete Deletes a base class pointer. The destructor of class does not call the destructor of the subclass, which can cause a memory leak.
The above is just a representation of polymorphism in simple inheritance, when using multiple inheritance, if subclasses inherit from N base class, then there will be n virtual tables, each base class causes the subclass to add a virtual table, when the base class A pointer is used to point to the subclass, will use the virtual table associated with base class A, in order to do this, the preprocessor needs to do more work, such as initializing or deleting the base class pointer, to make the necessary pointer adjustment steps to ensure correct. If you are using virtual inheritance, then the situation is more complicated, which I have not understood.
If you are using the derived class pointer to point to base class object, then always use the vptr in base class, then the behavior is always the base class. In general, subclasses always exhibit more specific behaviors, and subclasses have more manifestations, which is the meaning of polymorphism, and if you point to base class object with the derived class pointer, the polymorphic is discarded. Another problem is explained by the "extra" cost of using Inheritance: 1) The space occupied by vptr, 2) more time in the compilation period. But this extra is not absolute, think of the space and time spent in order to express the many forms of their own hand-crafted.

Conclusion

Several times to hear people talk about as long as the programming thought good, in C language can also write object-oriented program, yes, this sentence is not false, read more than C + + multi-state implementation of the way, the correctness of this sentence is further affirmed. But if you want to write the object-oriented program in C, it's better to change to C + +, why not give it to the computer? Labor-saving and more reliable-this means using a preprocessor.

Implementation of C + + polymorphism

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.