程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 純C語言簡單模擬C++的虛函數表

純C語言簡單模擬C++的虛函數表

編輯:關於C語言

純C語言簡單模擬C++的虛函數表


多態,面向接口編程等設計方法並沒有綁定到任何特定的語言上,使用純C也可以實現簡單的多態概念。下面給出一個非常簡單粗糙的例子,只為說明概念。

父類Animal定義
文件:animal.h

#ifndef ANIMAL_H
#define ANIMAL_H


/* 方法表, 類似於C++的虛函數表 */
typedef struct vtable vtable;
struct vtable
{
    void (*eat)();
    void (*bite)();
};

typedef struct Animal Animal;
struct Animal
{
    const vtable* _vptr;  /* 每一個對象都有一個指向虛表的指針*/
};

/*
 如果不用虛表的話,每個對象都要包含所有的接口函數指針, 而實際上所有同類型對象的這些指針的值是相同的,造成內存浪費。
 接口函數是和類型一對一的,而不是和對象一對一。

struct Animal
{
    void (*eat)();
    void (*bite)();
};

*/

#endif

子類Dog,文件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");
};

/* 虛表是在編譯時確定的 */
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; /*運行時,綁定虛表指針*/
        pDog->x = 0;
    }
    return (Animal*)pDog;
}

另一個子類Cat, 文件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.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());

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved