c中的多级继承

时间:2014-03-13 19:53:28

标签: c inheritance

在纯C中继承这样的继承

typedef struct {
    char name[NAMESIZE];
    char sex;
} Person;

typedef struct {
    Person person;
    char job[JOBSIZE];
} Employee;

typedef struct {
    Person person;
    char booktitle[TITLESIZE];
} LiteraryCharacter;

我知道可以将“LiteraryCharacter”类型的实例转换为“Person”类型,并将其用作此类。但是,将“LiteraryCharacter”类型的实例转换为“Employee”类型并使用它也是可以/安全吗?

3 个答案:

答案 0 :(得分:1)

这样的强制转换在标准C中是未定义的行为,尽管它可以与许多编译器一起使用。

即使它适用于您当前使用的编译器,也要注意它可能会在未来版本的编译器中或使用不同的编译器中断。 C标准允许编译器假设指向不同类型的指针不指向相同的内存 - 除了一些记录良好的异常,包括LiteraryCharacter *Person *的强制转换。将LiteraryCharacter *强制转换为Employee *的代码可以并且将在使用此假设生成有效代码的编译器下中断。

最好先解释为什么你认为你需要这个演员。它的等价在C ++中是非常不正确的,并在Java中生成ClassCastException。毕竟,LiteraryCharacter没有Person的字段,例如job

答案 1 :(得分:0)

那将是未定义的行为。在C中没有继承这样的东西。

如果结构完全相同的布局,那么可能会侥幸逃脱它,但这确实是非常脆弱的代码。

答案 2 :(得分:0)

未定义的行为:

在您的示例中,您将转换为来自不兼容的类型,由于这两种类型的大小不同,因此甚至无法编译。但是,您可以转换为兼容(或甚至不兼容)的指针类型,它将进行编译。

从不兼容(或者说是伪兼容)类型转换为未定义的行为,在某些结构和编译器实现上,它将对其他人不会起作用。

只要编译器正在处理对象结构/内部对齐/内存布局等,

转换为兼容 - 指针类型是安全的。(那里&# 39;以下是一个例子。)

" OK"部分是值得商榷的。它会起作用吗?是的,因为他们在记忆中有相同的""布局,你知道这个特定的事实。但是,当另一个程序员创建该结构时会发生什么?您必须阅读其来源以评估是否可以安全地转换为其他类型。

封装和未来验证:

此外,大多数封装技术只会暴露一种" opaque类型"你可以通过指针使用它 - 将它传递给在同一个库/包中实现的函数,并且它们完成所有结构特定的工作。对于"不透明类型"你只知道那个结构存在,你不知道它的内部结构,所以你不能只改变你用来访问它的指针类型,因为你不能确保它背后的结构兼容性。

封装的目的是允许单独开发模块。因此,当这个外部模块的原始开发人员在将来的版本中更改结构时,它会破坏与代码的兼容性(无论如何都不应该以这种方式使用它)。

更安全的方法:

这是GCC的非标准(但几乎无处不在)编译器功能。

typedef struct {
    char name[NAMESIZE];
    char sex;
} Person;

typedef struct {
    Person;
    char job[JOBSIZE];
} Employee;

typedef struct {
    Employee;
    char booktitle[TITLESIZE];
} LiteraryEmployeeCharacter;

LiteraryEmployeeCharacter* lec = malloc(sizeof(LiteraryEmployeeCharacter));
lec->name = "My character";
lec->sex = 'F';
lec->job = "Steward";
lec->booktitle = "A book";

通过使用未命名的字段,您可以访问namesexjob,就好像它们已在LiteraryEmployeeCharacter结构中定义一样。

通过强制转换为兼容的指针类型,编译器知道每个字段的确切结构和位置,并且可以轻松地正确处理结构。