假设我的child.h
文件中声明了以下不完整类型
typedef struct child * child_ptr;
我的child.c
文件中有不完整的完整类型定义
struct child {
char * type;
int age;
};
假设这是我的main.c
文件
// some code before the main
int main( void ) {
struct child *child = new_child( "Boy", 5 );
child->type; // i know i will get an error
}
与C ++不同,Java,C#,C对封装类型的支持有限。 C为封装提供的唯一工具是不完整的类型。这些是描述对象但缺少确定其大小所需信息的类型。这就是我编译程序后会出错的原因。那么,有没有办法访问它们?
我认为,实现此目的的一种方法是在我的child.h
文件中声明“公共”函数。例如,一个函数,它接受一个指向子对象的指针并返回存储在“type”成员变量中的值;但是,这会阻止数据隐藏。如果我将结构移动到child.h
文件,则默认情况下所有成员都是公共的。同样,这将阻止数据隐藏。
答案 0 :(得分:2)
您可以在child.h
文件中创建函数原型,该文件将struct child*
作为参数并返回不同的成员。
例如:
char * get_name(child_ptr chld);
在child.c
文件中,可以看到struct child
的定义,并在main.c
文件中使用它,如下所示:
child_ptr chld = new_child( "Boy", 5 );
char* child_name = get_name(chld);
答案 1 :(得分:1)
在child.h中提供所有公共成员的定义(并使它们在定义中排在第一位);
struct child{
/*public members*/
char private_parts[];
};
您无需提供对孩子私密部分的任何访问权限,如果您不希望其他任何人触摸它们,我也不会。它只是在那里证明你在这里看到的类型更多。
在child.c中创建另一种类型:
struct private_child{
struct child;
/*private members*/
};
struct child *new_child(/*Init Params*/){
struct private_child *tmp = malloc(sizeof *tmp);
/* Initialize the child */
return &tmp->child;
}
void use_child(const child *c){
struct private_child *pc = (struct private_child *)c;
/*access the private members*/
}
您可以在这里看到一些如何使用private_child创建新子项的示例,以及如何通过强制转换访问child.c中的私有成员。 这总是有效的,因为......
(C1x§6.7.2.1.13:“指向结构对象的指针,适当转换,指向它的 初始成员......反之亦然。结构中可能存在未命名的填充 对象,但不是在它的开头。“)
修改强>
在旧版本的C中,灵活长度的数组成员可能不可用,您可以忽略该子成员。这个数组实际上使你(可能)想要的类型不完整,所以没有人不小心尝试在自动存储中创建其中一个(它只能通过分配,并希望只使用你指定的“构造函数”)。我不确定在C中制作类型不完整的另一种方法。