typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo;
int b;
} bar;
基本上我想做:
bar b;
b.a;
我知道如果我在bar中命名了foo结构,我可以做b.foo_name.a,但我不想这样做。
有什么办法吗?
这个问题得到了各种不同的答案,所以让我解释一下这个问题。我想这样做的原因是因为我有一个我需要适应我的情况的库,这意味着我无法修改原始的struct decleration。此外,我需要做的就是在结构的开头添加1项(为什么开始?因为我有一个'object'结构,它可以处理项目中的所有结构)。我可以像你提到的那样简单地嵌入结构,但它真的很烦人,因为所有引用都需要输入'variable-> image.location'那个'图像'。键入十亿种类型真的很烦人。
答案 0 :(得分:25)
显然this feature has been added to C11,但是我无法访问最近年份的C编译器(> = GCC 4.6.2)。
typedef struct foo {
int a;
} foo;
typedef struct bar {
struct foo;
int b;
} bar;
int main() {
bar b;
b.a = 42;
b.b = 99;
return 0;
}
答案 1 :(得分:9)
您可以使用指针,因为保证指向结构对象的指针指向其第一个成员。参见例如this article
#include <stdlib.h>
#include <stdio.h>
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo super;
int b;
} bar;
int fooGetA(foo *x) {
return x->a;
}
void fooSetA(foo *x, int a) {
x->a = a;
}
int main() {
bar* derived = (bar*) calloc(1, sizeof(bar));
fooSetA((foo*) derived, 5);
derived->b = 3;
printf("result: %d\n", fooGetA((foo*) derived));
return 0;
}
答案 2 :(得分:7)
不可能以C
的方式进行。但您可以在foo
中模仿具有bar
成员变量的继承。
typedef struct bar_s {
foo obj;
int b;
} bar;
bar b;
b.obj.a = 10;
答案 3 :(得分:2)
如果你的话
typedef struct foo_s {
int a;
} foo;
typedef struct bar_s {
foo my_foo;
int b;
} bar;
所以你可以这样做:
bar b; b.my_foo.a = 3;
否则,由于sizeof(bar_s)
对编译时间不利,因此无法在C中执行此操作。这不是一个好习惯,但你可以在bar_s中保存一个void * ptr;
指针,另一个描述ptr
类型的枚举,并按类型转换。
即:
typedef enum internalType{
INTERNAL_TYPE_FOO = 0,
}internalType_t;
typedef struct bar_s {
internalType_t ptrType;
void* ptr;
int b;
} bar;
然后:
bar b; foo f;
b.ptrType = INTERNAL_TYPE_FOO;
b.ptr = &f;
以及代码中的其他地方:
if (b.ptrType == INTERNAL_TYPE_FOO) {
foo* myFooPtr = (foo *)b.ptr;
}
答案 4 :(得分:0)
您可以尝试使用继承:
struct foo_s
{
int a;
};
struct bar_s: foo_a
{
int b;
};
适用于C ++,不确定它是否适用于C。
答案 5 :(得分:0)
可以通过预处理器轻松完成:
创建名为base_foo.h
的文件:
int foo;
然后简单地加入它:
typedef struct foo_s {
#include "base_foo.h"
} foo;
typedef struct bar_s {
#include "base_foo.h"
int b;
} bar;
答案 6 :(得分:0)
匿名结构与具有无名字段的联合之间存在混淆。无名字段是Microsoft扩展程序。
struct known {
struct /* anonymous */ {
int anonymous;
};
int known;
};
匿名struct
或union
是struct
或union
,而没有tag name
嵌入另一个struct
或{{1 }}。它也不需要任何字段名称。
无名字段是Microsoft扩展,它允许在C中进行有限的继承。
union
至少在C11标准定义中,匿名struct A {
int a;
};
struct B {
struct A: // nameless field
int b;
};
或struct
不是无名字段,而无名字段也不是匿名。
答案 7 :(得分:0)
这是没有 c 标志的最简单方法
#include <stdio.h>
#define foo_s struct { int a; }
typedef foo_s foo;
typedef struct bar_s {
foo_s; // extends foo_s
int b;
} bar;
int main(void)
{
bar b = {
.a = 1,
.b = 2,
};
foo *f = (foo *)&b;
printf("a: %d\n", f->a);
return 0;
}
$ gcc inherit.c
$ ./a.out
a: 1