C language implementation polymorphism, C language Polymorphism

Source: Internet
Author: User

C language implementation polymorphism, C language Polymorphism

In the previous article "function pointers in the C language struct", we introduced the application of function pointers in the struct. This article starts further research.

Purpose of this article:

1. Consolidate the understanding of the object-oriented Mechanism

2. consolidate understanding of C Language

Address: Workshop.

The following concepts are taken from Wikipedia (http://zh.wikipedia.org/wiki/%E5%A4%9A%E5%9E%8B_ (% E7 % 89% A9 % E4 % BB % B6 % E5 % B0 % 8E % E5 % 90% 91% E7 % A8 % 8B % E5 % BC % 8F % E8 % A8 % AD % E8 % A8 % 88):

Polymorphism(Polymorphism) indicates that when an object-oriented program is running, the same message may be sent to multiple objects of different classes. The system can trigger the method of the corresponding class based on the class to which the object belongs, there are different behaviors. In short, polymorphism means that different objects with the same message will lead to different action claims. In object-oriented programming, polymorphism generally refersSubtype Polymorphism(Subtype polymorphism ).

If you haven't written C code for a long time, to ensure that your compiler still works, run the following basic program:

#include <stdio.h>int main(){     printf("Hello World");     return 0;}

OK. Now we are accelerating the process.

We will create three classes that inherit the abstract Shape class, but the C language does not have the concept of class or inheritance, but there is struct. Let's get started.

struct Square{    int width;    int height;};struct Circle{    float radius;};struct Triangle{    int base;    int height;};

Nothing special. Let's further study and put the following code into the main function.

printf("size of square is %d\n", sizeof(struct Square));printf("size of Circle is %d\n", sizeof(struct Circle));printf("size of Triangle is %d\n", sizeof(struct Triangle));

The output result is as follows (no guarantee depends on the platform ):

size of cube is 8size of circle is 4size of triangle is 8 

For memory alignment problems, refer to C language memory alignment details

If struct is used to simulate the class, the method in the class can use the function pointer. The C language treats the function pointer like other members,

Consider the following functions:

void print_square( void ){    printf("Hello Square\n");} 

This function accepts an empty parameter and returns NULL, which means that the pointer to this function is a function that accepts null parameters and returns an empty type. Here you can declare a variable like this:

struct Square{    int width;    int height;    //now for functions    void (* print)( void );    float (* area)( struct Square * this );}; 

For the C language variable declaration rules, refer to the famous book "C traps and defects".

Print is a pointer to a function with null parameters and null return values. Now we need to give Square an area function, accept itself as a parameter, and return a float type to represent the area. The READ function is similar to the print function.

Pointers are powerful, but they must point to useful things. But how do you know the address of a function in the memory? The good news is that the function name indicates its address in the memory, the following is an example:

struct Square square;square.print = print_square; 

Function pointers behave like other Members. When we create a Square with the square type and its value contains junk values, we need to manually assign them correct values. This kind of work requires a constructor and no C language, so we need to create a self-built constructor.

void init_square( struct Square * square, int w, int h ){    (*square).print = print_square;    (*square).width = w;    (*square).height = h;    (*square).area = calc_square_area;} 

This constructor is just another function that needs to pass a parameter that changes the value of square. Therefore, the parameter must be a pointer to Square and a value to be passed.

Let's test what we have done (square is used as an example ):

#include<stdio.h>struct Shape{    void (* print)( void );    float (* area)( struct Shape * this );    }; struct Square{    float width;    float height;    void (* print)( void );    float (* area)( struct Square * this );}; void print_square( void ){    printf("Hello Square\n");} float calc_square_area(struct Square * this){    return (*this).width * (*this).height;} void init_square(struct Square * square, float w, float h ){    (*square).width = w;    (*square).height = h;    (*square).print = print_square;    (*square).area = calc_square_area;} int main(void){    struct Square square;     init_square( &square, 2.5, 2.6 );    square.print();     printf("the area of the square is %.2f\n", square.area(&square));    return 0;}

We must create a Shape structure as the parent class of the other three shapes. We need to create the logical structure of the Shape structure:

// Abstract parent class struct Shape {void (* print) (void); float (* area) (struct Shape * this );};

Now that you know where to start, you can think about what we want to happen. If you want to create a Square multiple times, initialize it.

struct Square square;init_square(&square, 2, 4); 

To print it, call the function:

square.print(); 

If a pointer pointing to Shape tries to print square:

Struct Shape * pointer = (struct Shape *) & square; (* pointer). print ();//?? What will happen ??

An interruption error is returned, but the result is not as expected. We look forward to calling square by pointing to the Shape pointer.

Now let's take a look at memory-related, Shape and Square comparison.

Square:

Width Hight Print Area

16B

4 4 4

Shape:

Print Area

8B

4

The print () function contains the first 4 bytes in the Shape memory model and the third 4-byte position in the Square memory model.

square.print(); 

The above Code uses the pointer of the third byte to call the print function. The following Code expects the same functionality.

(*pointer).print(); 

But in the first four bytes there is no pointer, but an int value, two bytes, but our pointer will not realize that it is two bytes, therefore, the location of the memory is found to be 2 (which may be the memory address of some BIOS Drivers/operating systems), resulting in interruption errors.

Now that we know the reason, we can find a solution (not the best), only when the pointer of the print function in the Shape structure is in the third 4-byte position, the first eight bytes of the Shape can be filled. This method is the "fill" technology in C language. The Code is as follows:

struct Shape{    char padd[8];    void (* print)( void );    float (* area)( struct Shape * this );    }; 

The modified test code is as follows:

#include<stdio.h>//abstract father class/*struct Shape{    void (* print)( void );    float (* area)( struct Shape * this );    }; */struct Shape{    char padd[8];    void (* print)( void );    float (* area)( struct Shape * this );    }; struct Square{    float width;    float height;        //now for functions    void (* print)( void );    float (* area)( struct Square * this );}; void print_square( void ){    printf("Hello Square\n");} float calc_square_area(struct Square * this){    return (*this).width * (*this).height;} void init_square(struct Square * square, float w, float h ){    (*square).width = w;    (*square).height = h;    (*square).print = print_square;    (*square).area = calc_square_area;} int main(void){    struct Square square;     struct Shape *p = (struct Shape*)&square;    init_square( &square, 2, 2 );    //square.print();     (*p).print();    printf("the area of the square is %.2f\n", square.area(&square));    return 0;}

BTW: This article uses C to realize the polymorphism of OOP. It is not the best method. It is only implemented as a method and will be further optimized and improved later.

References:

Http://www.codeproject.com/Articles/739687/Achieving-polymorphism-in-C

 

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.