如何在普通C语言中继承结构
我在一个普通的C(嵌入式项目,很少的内存)中工作,我有一个结构如何在普通C语言中继承结构,c,inheritance,data-structures,C,Inheritance,Data Structures,我在一个普通的C(嵌入式项目,很少的内存)中工作,我有一个结构 typedef struct { int x; int y; int z; float angle; float angle1; float angle2; } Kind1; 有时我需要所有字段,有时我只需要x、y和角度 C++中,我将创建一个具有这3个字段的基类,将从另一个类继承3个字段,并根据每个需求实例化一个或另一个。如何在普通C中模拟这种行为 我知道我可以做一些像 typedef s
typedef struct
{
int x;
int y;
int z;
float angle;
float angle1;
float angle2;
} Kind1;
有时我需要所有字段,有时我只需要x、y和角度
C++中,我将创建一个具有这3个字段的基类,将从另一个类继承3个字段,并根据每个需求实例化一个或另一个。如何在普通C中模拟这种行为
我知道我可以做一些像typedef struct
{
int x;
int y;
float angle;
} Kind1;
typedef struct
{
Kind1 basedata;
int z;
float angle2;
float angle3;
} Kind2;
但我不能传递指向Kind2的指针,因为请求了指向Kind1的指针
我知道可以对指针进行类型转换和偏移,我只是想知道是否有更好、更安全的方法。您可以像在C++中一样执行此操作:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int z;
float angle2;
float angle3;
}
struct Kind
{
Kind1 k1;
Kind2 k2;
}
我知道可以对指针进行类型转换和偏移
不一定:
void foo(Kind1*);
struct Kind2
{
Kind1 basedata;
int z;
float angle2;
float angle3;
}
//...
Kind2 k;
foo(&(k.basedata));
这在普通C语言中是不可能的,这种语言没有这样的特性。但是,您可以使用预处理器宏简化类型转换和偏移量。在内存有限的情况下,通过声明两个不同的结构来保持完整性:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int x;
int y;
int z;
float angle;
float angle2;
float angle3;
}
我曾经不得不编写代码,使用联合和预处理器#define
s使代码看起来更可读。然而,这很快就会导致疯狂。如果这两个结构实际上是作为一个子类处理的,那么重新排列字段是最无害的:
struct Kind1
{
int x;
int y;
float angle;
}
struct Kind2
{
int x;
int y;
float angle;
// extended data:
int z;
float angle2;
float angle3;
}
只要它们与铸件一起小心使用。但是,如果出现任何错误,则应该进行调试版本名称检查,以证明所有操作都是正确的
struct Kind1
{
char variant[6]; // initialized to "kind1"
int x;
int y;
float angle;
}
struct Kind2
{
char variant[6]; // initialized to "kind2"
int x;
int y;
float angle;
// extended data:
int z;
float angle2;
float angle3;
}
function_expecting_kind2 (struct kind2 *p)
{
if (strcmp (p->variant, "kind2"))
error ("function expecting kind2 got '%s' instead", p->variant);
...
}
我能想到的一种方法将节省不超过2*sizeof(float)字节 在这里,整个节省将基于指针占用的内存量
仅在需要时初始化指针。下面的示例采用这些定义
struct base { char c; } *a_base;
struct sub { struct base b; int i; } *a_sub;
你的“例子”实际上是(最简单的)正确的解决方案 但我不能传递指向Kind2的指针,因为请求了指向Kind1的指针 是的,你可以。以下内容来自C11标准,但之前的修订版具有相同的保证[需要引用] n1570 6.7.1.1.15 。。。经过适当转换的结构对象指针指向其初始成员(如果该成员是位字段,则指向其所在的单元),反之亦然。结构对象中可能有未命名的填充,但在其开头可能没有 因此
(struct base*)a_sub==&a_sub->b
和((struct base*)a_sub)->c==a_sub->b.c
因此,只要您的“超级结构”是“子结构”的第一个成员,您就可以在通过引用访问时将一个视为另一个。基本上不要这样做
void copy(struct base *from, struct base *to)
{
*to = *from; // Oops, you just lost half your object.
}
该项目是为嵌入式设备设计的,其目的是为了节省内存,否则我只能一直使用Kind2。删除我的评论,为时已晚。谢谢。@Flot2011:听起来像是过早的优化,但您可以根据任何给定的用例使用Kind1、Kind2或Kind。的可能重复,包括语法错误。@wildplasser:奇怪的是,我错过了这一个,我试着先搜索。顺便说一句,语法错误-你是什么意思?很明显,这是一种伪代码。它被标记为“C”,所以它不应该是伪代码。WRT语法错误:1)结构定义应以“;”结尾2) 结构标记{Kind1,Kind2}在C中不引入typedef(显然,在伪代码中它可以做任何事情)
void copy(struct base *from, struct base *to)
{
*to = *from; // Oops, you just lost half your object.
}