隐藏 C 中的类型定义
我有一个 .c
文件(一个函数库),其中包含一个函数和如下定义:
typedef long double big;
big foo(int x) { ... }
我想创建该库的一个接口,一个 .h
。所以我这样做:
typedef long double big;
big foo(int);
并从 .c
文件中删除 typedef long double big;
。但通过这样做,我放弃了接口中 big
的类型定义,因此它并不是一个真正干净的接口。有什么想法如何解决这个问题吗?
我知道我可以在我的 .c
文件中执行此操作:
struct foo {
long double;
};
然后在 .h
文件中执行以下操作:
typedef struct foo big;
big foo(int);
但创建一个 struct
似乎很浪费仅针对一个字段,此外,每当我想读取 big
时,我都应该使用 .
运算符。
I have a .c
file (a library of functions) with a function and a definition like this:
typedef long double big;
big foo(int x) { ... }
I want to create an interface of this library, an .h
. So I do:
typedef long double big;
big foo(int);
and remove the typedef long double big;
from the .c
file. But by doing so I give away the type definition of big
in my interface, so it's not really a clean interface. Any ideas how to fix that?
I know I could do this in my .c
file:
struct foo {
long double;
};
and then in the .h
file do:
typedef struct foo big;
big foo(int);
But it seems waste to create a struct
for just one field, plus I should use the .
operator whenever I want to read a big
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果类型永远不会变得比 long double 更复杂,那么可能不值得有更多隐藏它的想法。如果它可能需要变得更复杂,那么您可以考虑使用不透明类型。在公共标头
big.h
中,您使用:所有函数都将获取并返回指向
big_t
类型的指针。这就是您对此类不完整类型所能做的全部事情。请注意,您的客户无法为自己分配任何big_t
值;他们不知道该类型有多大。这意味着您最终可能会得到以下函数:创建和销毁
big_t
值。然后他们将能够进行算术运算:等等。但是因为他们只有不透明的、不完整的类型,所以他们不能可靠地在
big_t
结构中乱搞。但请注意,您只能在接口中使用指针。传递或返回值需要完整的类型,如果类型完整,用户可以研究其内部工作原理。在实现标头
bigimpl.h
中,您将拥有:您的实现代码将仅包含
bigimpl.h
,但包含big.h.这里的主要问题是确保您知道如何处理内存分配。
有时这种技术是值得的。通常这并不是真正必要的。您需要自己进行评估。
If the type is never going to get more complex than
long double
, then it probably isn't worth having conniptions about hiding it more. If it might need to become more complex, then you can consider using an opaque type. In your public header,big.h
, you use:All the functions will take and return pointers to the
big_t
type. This is all you can do with incomplete types like that. Note that your customers cannot allocate anybig_t
values for themselves; they don't know how big the type is. It means you'll probably end up with functions such as:to create and destroy
big_t
values. Then they'll be able to do arithmetic with:Etc. But because they only have an opaque, incomplete type, they cannot reliably go messing around inside a
big_t
structure. But note that you are constrained to using pointers in the interface. Passing or returning values requires complete types, and if the type is complete, users can investigate its inner workings.In the implementation header,
bigimpl.h
, you'll have:And your implementation code will only include
bigimpl.h
, but that includesbig.h
. The main issue here is making sure you know how the memory allocations are handled.Sometimes this technique is worthwhile. Often it is not really necessary. You'll need to make the assessment for yourself.
为何如此?谁在乎你的代码的用户是否可以看到 typedef?怎么感觉很痛……有什么吗?他们需要一种方法来使用你的 typedef,这就是它的完成方式。对我来说,这听起来像是一个理论问题,没有明显的不良影响。你担心的是错误的事情。
是的,那很愚蠢。另外,现在您已经放弃了结构的定义!哦不!这与公开 typedef (或任何其他类型)有什么不同?
How so? Who cares if users of your code can see the typedef? How does it hurt... anything? They need a way to use your typedef and this is how it is done. Sounds like a theoretical problem to me that has no appreciable ill effects. You're worrying about the wrong thing(s).
Yup, that is silly. Also, now you've given away the definition of your struct! Oh no! How is that any different than exposing the typedef (or any other type)?