C Language Object-oriented programming (III): virtual function and polymorphic __php

Source: Internet
Author: User
Tags class definition

In the book "C + + programming thought" The realization mechanism of virtual function is described in detail, a generic compiler inserts a hidden code at compile time, saves the type information and the virtual function address, and when invoked, this hidden code can find a virtual function implementation that is consistent with the actual object.

We are here to provide an implementation in C that mimics the VTABLE mechanism, but everything needs to be assembled in our own code.

Earlier on the Internet to see a description of the C language to implement virtual functions and polymorphism of the article, talking about the use of the base class to save the pointer to the derived class, in the derived class to save the pointer to the base class to achieve mutual invocation, the protection of the base class, derived classes when using virtual functions and I think this method has a lot of limitations, not to mention the level of inheritance problems, simply saving a derived class pointer in a base class has violated the original meaning of virtual functions and polymorphism-polymorphism is the use of derived classes through the base class interface, if the base class also needs to know the information of the derived class ....

My basic idea is:

Explicitly declare a void** member in the base class, as an array to hold all function pointers for the base class definition, and declare a member of type int that indicates the length of the void* array. The position of each function pointer defined by the "base class" in the array, the order is fixed, this is the convention, each "derived class" must be populated with a function pointer array of the base class (possibly dynamically growing), and without overriding the virtual function, the corresponding position is placed in the function implementation of the 0 "base class", traversing the array of function pointers, Find the last 0 function pointer in the inheritance hierarchy, which is the function implementation that corresponds to the object that should be called actually

Okay, let's take a look at the code:

struct Base {
    void * * vtable;
    int vt_size;
    
    void (*func_1) (struct base *b);
    Int (*func_2) (struct base *b, int x);

struct derived {
    struct base b;
    int i;
};

struct derived_2{
    struct derived D;
    char *name;
};
The code above is what we're going to talk about, first of all, in C, with the function pointers in the structure body and C + + member functions, C in this way, all functions are inherently virtual functions (pointers can be modified at any time).

Note that derived and derived_2 do not define func_1 and func_2. In the virtual function implementation of C, if a derived class wants to override a virtual function, it does not need to be explicitly declared in a derived class. To do this, implement the function you want to rewrite in the implementation file, and fill in the constructor with an overridden function in the virtual function table.

We face a problem where the derived class does not know where the function implementation of the base class is (from the high cohesion, the low coupling principle), how to initialize the virtual function table when constructing the derived class instance. In C + + The compiler automatically invokes the constructor of all parent (ancestor) classes on the inheritance hierarchy, or it can explicitly call the constructor of the base class in the initialization list of the constructor of the derived class. What to do.

We offer a less elegant solution:

When each class is implemented, it provides two functions, a constructor, an initialization function that the user generates a class, which is used by the inheritance hierarchy immediately to invoke its own class to initialize the virtual function table correctly. Based on such a principle, a derived class needs only to invoke the initialization function of the direct base class, which is guaranteed by each derived class, and everything can go on.

Here are two functions to implement:

struct derived *new_derived ();
void initialize_derived (struct derived *d);
The function that begins with new is the constructor, and the function that begins with initialize as the initialization function. Let's take a look at the implementation framework for the New_derived constructor:

struct derived *new_derived ()
{
    struct derived * d = malloc (sizeof (struct derived));
    Initialize_base ((struct base*) d);
    Initialize_derived (d);/* Setup or modify VTABLE/return
    D;
}
If the constructor for Derived_2 is New_derived_2, then only call initialize_derived can be invoked.

After that, the constructor function is said to be a destructor, and the destructor function is a virtual function. When you delete an object, you need to call the destructor of the base class at the top of the inheritance hierarchy from the destructor of the derived class. This can also be guaranteed in C. The practice is to explicitly declare a destructor for the base class, to find the virtual function table in the implementation of the base class, and to invoke it from the back-forward. The function declaration is as follows:

struct Base {
    void * * vtable;
    int vt_size;
    
    void (*func_1) (struct base *b);
    Int (*func_2) (struct base *b, int x);
    void (*deletor) (struct base *b);

After talking about construction and deconstruction, it's time to say what the virtual function table is. We first draw a picture, or with just the base, derived, derived_2 as an example to illustrate, a look at the picture will understand:



We assume that the derived class implements three virtual functions, the Derived_2 class implements two, func_2 is not implemented, and the above diagram is the final virtual function table owned by the Derived_2 instance, and the length of the table (Vt_size) is 9. If it is an instance of derived, there is no last three entries in the table, and the length of the table (Vt_size) is 6.

What must be limited is that the base class must implement all the virtual functions, and only in this way can this set of implementation mechanisms run. Because everything happens from the implementation function of the base class, we can find the realization function of the derived class by traversing the virtual function table.

When we access func_1 through a base-type pointer (actually pointing to an instance of Derived_2), the func_1 of the base class implementation finds the derived_2_func_1 in the VTABLE to invoke.

OK, so far, basically understand the principle of implementation, as to how the initialization function assembly virtual function table, the base class of virtual function implementation, can be based on the above ideas to write code. The virtual functions implemented in my method are accessed through the base class pointer, and the behavior is basically consistent with C + +.

Review:

C Language object-oriented Programming (i): encapsulation and Inheritance C language object-oriented programming (ii): detailed inheritance

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.