如您所知,您不能这样做。但是,也有一些成语可以产生类似的效果。
C 将允许您做一些类似于面向对象设计中所谓的“pimpl”习语的事情。您的结构可以有一个不透明的指针,指向另一个前向声明的结构,该结构充当结构的私有数据。对结构进行操作的函数代替成员函数,可以拥有私有成员的完整定义,并且可以使用它,而代码的其他部分则不能。例如:
在标题中,foo.h:
struct FooPrivate;
struct Foo {
/* public: */
int x;
double y;
/* private: */
struct FooPrivate* p;
};
extern struct Foo* Foo_Create(); /* "constructor" */
extern void Foo_DoWhatever(struct Foo* foo); /* "member function" */
在实现中,foo.c:
struct FooPrivate {
int z;
};
struct Foo* Foo_Create()
{
struct Foo* foo = malloc(sizeof(Foo));
foo->p = malloc(sizeof(FooPrivate));
foo->x = 0;
foo->y = 0;
foo->p->z = 0;
return foo;
}
void Foo_DoWhatever(struct Foo* foo)
{
foo->p->z = 4; /* Can access "private" parts of foo */
}
在程序中:
#include "foo.h"
int main()
{
struct Foo* foo = Foo_Create();
foo->x = 100; /* Can access "public" parts of foo */
foo->p->z = 20; /* Error! FooPrivate is not fully declared here! */
Foo_DoWhatever(foo); /* Can call "member" function */
return 0;
}
注意需要使用“构造函数”来为私有数据分配内存。显然,您需要将其与特殊的“析构函数”功能配对,以便正确释放私有数据。
或者,或者,如果您希望您的结构没有任何公共字段,您可以使 整个 结构不透明,而只是让标题类似于
struct Foo;
extern struct Foo* Foo_Create(); /* "constructor" */
extern void Foo_DoWhatever(struct Foo* foo); /* "member function" */
使用 foo.c 中 struct Foo 的实际定义,以及可用于您希望提供直接访问的任何属性的 getter 和 setter 函数。