C language Polymorphism

Source: Internet
Author: User

C language 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 inherited from the abstract Shape class, but the C language does not have the concept of class or inheritance, but there is struct. Let's start with it. Struct Square {int width; int height ;}; struct Circle {float radius ;}; struct Triangle {int base; int height ;}; nothing special. Let's further study, 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); output result ): size of cube is 8 size of circle is 4 size of triangle is 8 memory alignment involved For details about the problem, refer to "Explanation of C language memory alignment". If struct is used to simulate the class, the method in the class can adopt the function pointer. The C language treats the function pointer like other members, consider the following function: void print_square (void) {printf ("Hello Square \ n");} This function accepts an empty parameter and returns an empty value, this means that the pointer to this function is a pointer to a function that accepts null parameters and returns NULL types. Here you can declare such a variable: struct Square {int width; int height; // now for functions void (* print) (void); float (* area) (struct Square * this) ;}; about the C language variable declaration rules, you can 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 to accept itself. Is a parameter, and a float type is returned 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. print = print_square; the function pointer acts like other Members. When we create a Square, its value contains the garbage value, 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. You need to pass the parameter that changes the value of square. Therefore, the parameter must be a pointer to Square and the value to be passed. Let's test our work (take square as an example): # include <stdio. h> struct Shape {void (* print) (void); float (* area) (struct Shape * this) ;}; struct Square {float width; float height; voi D (* 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 Sq Uare 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, next, let's think about what we want to happen. If you want to create a Square multiple times and initialize it struct Square; init_square (& square, 2, 4); if you want to print it, call the function: square. print (); if there is 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 the memory. Comparison between Shape and Square: width hight print area 16B 4 4 4 4 Shape: the print area 8B 4 4 print () function in the Shape memory model is the first 4 bytes, and the Square memory model is the third 4-byte location. print (); the above Code uses the pointer of the third byte to call the print function. The following Code expects the same function (* pointer ). print (); but in the first four bytes there is no pointer, but the int type value, two bytes, but our pointer will not realize that it is two bytes, so we can find the location of memory 2 (which may be the address of some BIOS Drivers/operating system memory), which leads to the interruption error. Now that we know the cause, you 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, you can fill the first 8 bytes of the Shape, 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 ;}

Related Article

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.