2016-04-14 10 views
0

Ich versuche, mich selbst Grundlagen der objektorientierten C. Ich versuche, Vtables zu bauen und dann diese zu verwenden, um "Vererbung" von Strukturen zu simulieren (versuchen Sie, Klassenvererbung in C++ zu kopieren).Objektorientierte C: Gebäude vtables

Ich habe eine Frage .. Ich glaube, es ist möglich, aber ich weiß nicht, wie es geht. Kann die Variable der "abgeleiteten" Struktur vom Zeiger der "Basis" Struktur modifiziert werden?

#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; 
} 

Nun lassen Sie uns sagen, ich versuche, 2. int-Variable (Gewicht oder NumLives je) zu modifizieren, wie würde ich es *a mit ändern? Ich versuche, von Object oriented programming with ANSI-C zu lernen, aber ich kann das nicht herausfinden.

+1

Wenn Sie einen vom Typ Hund im Voraus wissen, tun gerade ((Dog *) a) -> Gewicht = 33,3; Aber in diesem Fall verlierst du die Abstraktion von oop. – fluter

+0

Ich kann immer noch einen 'Schalter' oder etwas Ähnliches verwenden und bestimmen, um welches Tier es sich handelt. Das sieht ziemlich gut aus, denke ich. Wird ein bisschen testen! – Rorschach

+0

Ihr Code ist kaputt. C definiert nicht Casting von-zu beliebigen Typ. – 2501

Antwort

0

können Sie verwenden ((Dog *)a) -> weight = 42.0; oder ((Cat *)a) -> numberOfLives = 9;