如何在C编程中访问不完整类型的成员

时间:2014-05-27 12:12:18

标签: c

假设我的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文件,则默认情况下所有成员都是公共的。同样,这将阻止数据隐藏。

2 个答案:

答案 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中制作类型不完整的另一种方法。