2016-04-14 15 views
0

Kendime, nesneye yönelik temel kavramları öğretmeye çalışıyorum C. Vtables oluşturmaya çalışıyorum ve bunları yapıların "mirasını" simüle etmek için kullanıyorum (C++ sınıf mirasını kopyalamaya çalışın).Nesne yönelimli C: Bina vtables

Bir sorum var .. Bunun mümkün olduğuna inanıyorum, ama nasıl yapacağımı bilmiyorum. "Türetilmiş" yapının değişkeni "taban" yapısının işaretçisinden değiştirilebilir mi?

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

Şimdi, o *a kullanarak nasıl değiştireceği, ı 2 int değişken (ağırlık veya NumLives, bağlı) değiştirmeye çalışabilirler diyelim? Object oriented programming with ANSI-C'dan ders çalışıyorum ama bunu anlayamıyorum.

+1

önceden tipi Köpek bir olduğunu biliyorsanız ((Cat *)a) -> numberOfLives = 9;, sadece ((Köpek *) a) yapmak kullanabilirsiniz -> ağırlık = 33.3; Ama bu durumda oopun soyutlanmasını kaybedersiniz. – fluter

+0

Hala bir "anahtar" ya da benzer bir şey kullanabilir ve Hayvanın ne olduğunu belirleyebilirim. Yani bence bu oldukça iyi görünüyor. Birazdan test edecek! – Rorschach

+0

Kodunuz bozuk. C, rasgele türden döküm tanımlamaz. – 2501

cevap

0

Sen ((Dog *)a) -> weight = 42.0; veya

İlgili konular