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.
ö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. – fluterHala 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
Kodunuz bozuk. C, rasgele türden döküm tanımlamaz. – 2501