面向对象的C:构建vtable

时间:2016-04-14 00:03:55

标签: c oop inheritance

我正在尝试自学基于面向对象的C语言。我正在尝试构建vtable,然后使用它们来模拟结构的“继承”(尝试在C ++中复制类继承)。

我有一个问题..我相信这是可能的,但我不知道该怎么做。可以从“base”结构的指针修改“派生”结构的变量吗?

#include <stdio.h>
#include <stdlib.h>

//should represent Base
typedef struct Animal
{
    int age;
    void *vtable;
} Animal;

//Cat and dog will inherit Animal. They both have same 'age' variable, and different other parameters
typedef struct Dog
{
    int age;
    double weight;
    void *vtable;
} Dog;

typedef struct Cat
{
    int age;
    int numberOfLives;
    void *vtable;
} Cat;

//some test functions
void Speak_Dog(Animal* a)
{
    printf("Woof!\n");
}

void Speak_Cat(Animal* a)
{
    printf("Meow!\n");
}

//this is where I'm stuck, I would like to keep sending pointer to Animal
double Dog_GetCost(Animal *a)
{
    return 0;//should return age*weight
}

double Cat_GetCost(Animal *a)
{
    return 0;  //should return age*num_lives
}

//build tables
void* Dog_Vtable[2] = {Speak_Dog, Dog_GetCost};
void* Cat_Vtable[2] = {Speak_Cat, Cat_GetCost};

void Construct_Dog(Dog* d)
{
    d->age = 0;
    d->weight = 0;
    d->vtable = Dog_Vtable;
}

void Construct_Cat(Cat* c)
{
    c->age = 0;
    c->numberOfLives = 0;
    c->vtable = Cat_Vtable;
}

int main()
{
    int choice;
    Dog d;
    Cat c;
    Animal* a;

    ((void (*)(Animal*))Dog_Vtable[0])((Animal*)&d);  //print out "woof" - good
    ((void (*)(Animal*))Cat_Vtable[0])((Animal*)&c);  //print out "meow" - good

    printf("Do you want to make dog or a cat? (0/1) ");
    scanf("%d", &choice);

    if(choice == 0)
    {
        a = &d;  //animal is Dog
        a = (Animal*)malloc(sizeof(Dog));  //allocate memory for Dog
        Construct_Dog(a);  //construct it
    }
    else
    {
        a = &c;  //similar for cat
        a = (Animal*)malloc(sizeof(Cat));
        Construct_Cat(a);
    }

    free(a);

    return 0;
}

现在,假设我尝试修改第二个int变量(weight或NumLives,取决于),我将如何使用*a更改它? 我正在尝试向Object oriented programming with ANSI-C学习,但我没有想到这一点。

1 个答案:

答案 0 :(得分:0)

您可以使用((Dog *)a) -> weight = 42.0;((Cat *)a) -> numberOfLives = 9;