Reputation: 23
I would like to simulate the object oriented programming, so in C++, let's consider the following C code:
typedef struct tAnimal{
char * name;
int age;
}tAnimal;
typedef struct tAnimal2{
char * name;
int age;
float size;
}tAnimal2;
In C++ you can create a table of different objects which are inherited from the same class. I would like to do the same in C, let's consider the following code:
tAnimal ** tab;
tab = malloc(sizeof(tAnimal*)*2);
tab[0] = malloc(sizeof(tAnimal));
tab[1] = malloc(sizeof(tAnimal2));
Notice that the allocation works because malloc returns a void pointer, and C does not require casting. But I still have no access to the size field, because the type of tab elements is tAnimal after all.
Is there anyway to fix this?, I would like to stay away from void ** pointers.
Upvotes: 2
Views: 3950
Reputation: 17179
In order to access the size
field in tab[1]
you can cast the pointer to a tAnimal2 pointer.
tAnimal2* panimal2 = (tAnimal2*) tab[1];
panimal2->size = 1.0;
However this practice is prone to data corruption since you will need a method to ensure that the element of the table you cast to tAnimal2 is indeed an instance of tAnimal2. You could use an additional type field as Joachim Pileborg suggests to check the type of the object.
Upvotes: 0
Reputation: 409482
In C it's common to use a structure with a type-flag, and a union
of the data:
typedef enum
{
Animal1,
Animal2
} AnimalType;
struct Animal
{
AnimalType type;
union
{
tAnimal animal;
tAnimal2 animal2;
};
};
Now you can create an array of the Animal
structure.
Upvotes: 3
Reputation: 433
If you want to access the size field you have to cast your pointer to tAnimal2. Note, the same would be true for C++.
You can kind of simulate inheritance by embedding the first struct at the beginning of the second:
struct tAnimal{
char * name;
int age;
};
struct tAnimal2{
struct tAnimal parent;
float size;
};
Upvotes: 0