我想模拟面向对象的编程,所以在C ++中,让我们考虑以下C代码:
typedef struct tAnimal{
char * name;
int age;
}tAnimal;
typedef struct tAnimal2{
char * name;
int age;
float size;
}tAnimal2;
在C ++中,您可以创建一个包含从同一个类继承的不同对象的表。 我想在C中做同样的事情,让我们考虑以下代码:
tAnimal ** tab;
tab = malloc(sizeof(tAnimal*)*2);
tab[0] = malloc(sizeof(tAnimal));
tab[1] = malloc(sizeof(tAnimal2));
请注意,分配有效,因为malloc返回一个void指针,而C不需要强制转换。但是我仍然无法访问size字段,因为tab元素的类型毕竟是tAnimal。
无论如何要解决这个问题吗?我想远离无效指针。
答案 0 :(得分:3)
在C语言中,通常使用带有type-flag和union
数据的结构:
typedef enum
{
Animal1,
Animal2
} AnimalType;
struct Animal
{
AnimalType type;
union
{
tAnimal animal;
tAnimal2 animal2;
};
};
现在您可以创建Animal
结构的数组。
答案 1 :(得分:0)
如果要访问size字段,则必须将指针强制转换为tAnimal2。注意,C ++也是如此。
您可以通过在第二个结构的开头嵌入第一个结构来模拟继承:
struct tAnimal{
char * name;
int age;
};
struct tAnimal2{
struct tAnimal parent;
float size;
};
答案 2 :(得分:0)
为了访问size
中的tab[1]
字段,您可以将指针强制转换为tAnimal2指针。
tAnimal2* panimal2 = (tAnimal2*) tab[1];
panimal2->size = 1.0;
但是,这种做法容易导致数据损坏,因为您需要一种方法来确保您投射到tAnimal2的表的元素确实是tAnimal2的实例。您可以使用其他类型字段,因为Joachim Pileborg建议检查对象的类型。