假设我们有两个不同的struct
,它们主要是常见的字段,但有一个或两个不同的字段或更少的字段。例如:
typedef struct HobbyNodetag {
char *name; // hobby name
struct HobbyNodetag* link; // link to next HobbyNode
int count; // number of times this hobby was mentioned by user
// more fields...
// but identical type/variable name with MyHobbyList
} HobbyNode; // database of entire hobby node; singly linked list
typedef struct MyHobbyTag{
char *name; // hobby name
struct MyHobbyTag* link; // linked to next MyHobbyNode
// more fields...
// but identical type/variable name with EntireHobbyList
} MyHobbyNode; // single person's hobby node; singly linked list
我们是否有更高效/优雅的编码习惯才能使用上述两个struct
s?这是不是浪费了两个不同的struct
,因为他们分享了大部分领域?
更新
我之前的问题是误导性的。以上示例是节点并单链接(通过link
)。
答案 0 :(得分:6)
您可以将所有额外字段(存在于第二个结构中但不存在于第一个结构中)移动到结构类型定义的末尾,然后使用较小的结构作为较大结构的“基础”: / p>
struct BaseFoo {
int count;
char name[128];
float value;
};
struct ExtendedFoo {
struct BaseFoo base;
struct ExtendedFoo *next;
};
这个解决方案的优点是你可以拥有“多态”:因为C标准保证在内存中第一个struct成员之前没有填充,这样就可以了:
void print_name(struct BaseFoo *foo)
{
printf("Count: %d\n", foo->count);
printf("Name: %s\n", foo->name);
}
struct ExtendedFoo foo = { /* initialize it */ };
print_name((BaseFoo *)&foo);
答案 1 :(得分:1)
你可以做这样的事情,但我相信这不是你想要的。
typedef struct myHobbyTag{
char *name;
struct myHobbyTag* link;
} MyHobbyList;
typedef struct entireHobbytag {
MyHobbyList commonPart;
int count;
} EntireHobbyList;
答案 2 :(得分:0)
如果将所有公共字段移到顶部,则可以在C中使用OOP声明基类和继承类(在StackOverflow上搜索它。)
基本上有两种方法可以做到这一点。
您声明了一个基类,然后在继承类(包含更多字段)中将基类作为成员放在继承类的顶部。
struct hobbyLink; //常用链接
typedef struct baseHobbytag {
char *name;
struct hobbyLink* link;
} BaseHobby;
typedef struct myHobbyTag{
BaseHobby hobby;
int count;
// more fields...
} HobbyTag;
对所有公共基本成员使用#define,并将#define放在所有继承类中。
#define BASEHOBBY_MEMBERS \
char *name; \
struct hobbyLink* link;
// base class
typedef struct baseHobbytag {
BASEHOBBY_MEMBERS
} BaseHobby;
// Inherit basehobby
typedef struct myHobbyTag{
BASEHOBBY_MEMBERS
int count;
// more fields...
} HobbyTag;