Simulate the virtual function table of C ++ in pure C Language
Polymorphism, interface-oriented programming, and other design methods are not bound to any specific language. Pure C can also be used to implement simple polymorphism. The following is a very simple and rough example to illustrate the concept.
Parent class Animal Definition
File: animal. h
# Ifndef ANIMAL_H # define ANIMAL_H/* method table, similar to the virtual function table of C ++ */typedef struct vtable; struct vtable {void (* eat )(); void (* bite) () ;}; typedef struct Animal; struct Animal {const vtable * _ vptr;/* each object has a pointer to a virtual table */}; /* if no virtual table is needed, each object must contain all interface function pointers. In fact, the values of these pointers for all objects of the same type are the same, resulting in a waste of memory. Interface functions are one-to-one with types, rather than one-to-one with objects. Struct Animal {void (* eat) (); void (* bite) () ;}; */# endif
Subclass Dog, file dog. h
#ifndef DOG_H#define DOG_H#include "animal.h"typedef struct Dog Dog;struct Dog{ Animal base_obj; int x;};Animal* create_dog();#endif
Dog. c
# Include
# Include
# Include "dog. h "static void dog_eat () {printf (" dog_eat () \ n ") ;}; static void dog_bite () {printf (" dog_bite () \ n ");}; /* the virtual table is determined during compilation */static const vtable dog_vtable = {dog_eat, dog_bite}; Animal * create_dog () {Dog * pDog = malloc (sizeof (Dog); if (pDog) {pDog-> base_obj. _ vptr = & dog_vtable;/* when running, bind the virtual table pointer */pDog-> x = 0;} return (Animal *) pDog ;}
Another sub-class Cat, file cat. h
#ifndef CAT_H#define CAT_H#include "animal.h"typedef struct Cat Cat;struct Cat{ Animal base_obj; float y;};Animal* create_cat();#endif
Cat. c
#include
#include
#include "animal.h"#include "cat.h"static void cat_eat(){ printf("cat_eat()\n");};static void cat_bite(){ printf("cat_bite()\n");};static const vtable cat_vtable = { cat_eat, cat_bite};Animal* create_cat(){ Cat * pCat = malloc(sizeof(Cat)); if(pCat){ pCat->base_obj._vptr = &cat_vtable; pCat->y = 0.0; } return (Animal*)pCat;}
Main file main. c
#include
#include "animal.h"#include "cat.h"#include "dog.h"void ShowBite(Animal* pAnimal){ pAnimal->_vptr->bite();}void main(){ ShowBite(create_dog()); ShowBite(create_cat());}