我正在寻找一种方法来创建只能从一组特定的函数调用(setBit(bit_typ * const t),getBit(bit_typ * const t))访问或操作的私有样式typedef。我正在寻找一种不使用malloc的方法,有没有人有任何想法?
编辑://这个问题与this one不同,因为它正在寻找方法来接近"私人"结构而另一个问题(TL; DR是否有一种方法来定义一个opaque类型,它仍然可以在堆栈上分配,而且不会破坏严格的别名规则?)寻找一个解决问题的方法来解决与我的问题的一个可能的解决方案。
答案 0 :(得分:5)
一种方法是公开opaque类型的总 size ,并使用use将opaque类型的对象声明为unsigned char [N]
缓冲区。例如,假设您有一些类型OpaqueType
,其内部要隐藏用户。
在头文件中(向用户公开),你可以这样做
typedef unsigned char OpaqueType[16];
其中16
是要隐藏的类型的确切字节大小。在头文件中,您可以根据该类型编写整个接口,例如
void set_data(OpaqueType *dst, int data);
在实现文件中,您声明实际类型
typedef struct OpaqueTypeImpl
{
int data1;
double data2;
} OpaqueTypeImpl;
并实现以下功能
void set_data(OpaqueType *dst, int data)
{
OpaqueTypeImpl *actual_dst = (OpaqueTypeImpl *) dst;
actual_dst->data1 = data;
}
您还可以添加静态断言,以确保sizeof(OpaqueType)
与sizeof(OpaqueTypeImpl)
相同。
当然,正如下面的评论中所指出的那样,必须采取额外的步骤来确保这些对象的正确对齐,例如C11中的_Alignas
或者#34;中的某些基于联合的技术。经典"下进行。
通过这种方式,您可以让用户有机会声明OpaqueType
的非动态对象,即您不会强制用户在内部调用将malloc
此类对象的函数。与此同时,您不会向用户展示有关您的类型内部结构的任何信息(除了它的总大小和对齐要求)。
另请注意,以这种方式声明的OpaqueType
是一个数组,这意味着它不可复制(除非您使用memcpy
)。如果您想积极阻止无限制的用户级复制,这可能是一件好事。但是,如果要启用复制,可以将数组包装到结构中。
这种方法并不是非常优雅,但是当你想要保持你的类型的对象可由用户自定义时,这可能是隐藏实现的唯一方法。