什么定义了 C 中的不透明类型,它们什么时候需要和/或有用?
Posted
技术标签:
【中文标题】什么定义了 C 中的不透明类型,它们什么时候需要和/或有用?【英文标题】:What defines an opaque type in C, and when are they necessary and/or useful? 【发布时间】:2011-01-19 01:50:23 【问题描述】:我已经看到了一些“不透明类型”的概念,但我真的没有找到一个简洁的答案来说明什么定义了 C 中的不透明类型,更重要的是,它们允许我们用它们的存在解决什么问题.谢谢
【问题讨论】:
FILE
是 C 标准中不透明类型的一个很好的例子。您所需要的只是一个FILE *
对象,并使用对其进行操作的标准C 函数。作为程序员,你并不关心 FILE
类型由什么组成。
pthread_t
是不透明类型
【参考方案1】:
在我的理解中,不透明类型是那些允许您持有指向结构的句柄(即指针),但不能直接修改或查看其内容的类型(如果您完全允许,您可以通过帮助程序进行操作)了解内部结构的函数)。
不透明类型在某种程度上是使 C 更加面向对象的一种方式。它们允许封装,因此类型的内部细节可以改变——或者在不同的平台/情况下以不同的方式实现——而不必改变使用它的代码。
【讨论】:
Quibble:这个成语只是关于封装。封装对于面向对象来说是必要的,但它是其中最小的一部分。 没错,对于任何几乎面向对象的东西来说,它需要的远不止这些。尽管如此,当我用 C 语言编写时,我发现我总是缺少面向对象设计的一部分。另外,如果您要尝试模拟继承和C 中的多态性(工作量大于价值),您几乎肯定需要从不透明类型开始。 请记住,c 和它所产生的文化可以追溯到面向对象还很少见且仍处于实验阶段的时代。那个时代的程序和功能程序员将封装作为控制互连和不必要的复杂性的手段。将 c 中的不透明类型作为一种残缺的对象谈论是在将外来的 POV 推向该语言。 – dmckee 10 分钟前 @dmckee 不仅仅是为了封装。您也可以使用不透明类型来实现继承/多态,即使这可能不是不完整类型的初衷。无论如何,最重要的面向对象是一种程序设计方法,它不是语言特性。无论使用哪种语言,您都应该始终使用面向对象的程序设计!设计完成后,您可以查看可用的语言功能,并检查如何最好地以特定语言实现您的设计。【参考方案2】:不透明类型是通过指针在 API 中公开但从未具体定义的类型。
【讨论】:
【参考方案3】:它最常用于图书馆目的。 c 中 Opaque 类型背后的主要原则是通过指针使用数据,以隐藏数据处理实现。由于实现是隐藏的,您可以修改库而无需重新编译任何依赖它的程序(如果尊重接口)
例如: 版本 1:
// header file
struct s;
int s_init(struct s **x);
int s_f(struct s *x);
int s_g(struct s *x);
// source file
struct s int x;
int s_init(struct s **x) *x = malloc(...);
int s_f(..) ...
int s_g(..) ...
第 2 版
// header file
struct s;
int s_init(struct s **x);
int s_f(struct s *x);
int s_g(struct s *x);
// source file
struct s int y; int x;
int s_init(struct s **x) *x = malloc(...);
int s_f(..) ...
int s_g(..) ...
在您的程序方面,没有任何改变!并且如前所述,无需重新编译依赖它的每个程序。
【讨论】:
我假设“//实现”部分不属于同一个“//头文件”,库中包含哪些内容?此外,您似乎在标头中声明了struct s
,但在实现之前从未定义它。我最近读了一篇关于extern
C 中的变量***.com/questions/1433204/… 的好文章,这些概念看起来非常相似,不应该在您的示例代码中将struct s
声明为extern struct s
?
using extern for variable 一般用于声明全局变量(与我们的案例绝对无关)。这里是指令 struct s;在这里向编译器指示存在名为 struct 的类型。由于头文件中的所有 API 仅使用指向此结构的指针。它不需要知道结构的大小,而是结构指针的大小(由编译器定义)。为简化起见,它允许程序通过使用对象的地址(指向结构的指针)来使用对象
siegeX:我更改了帖子以避免对实施的混淆
@SiegeX 在 C 中不存在需要将非常量变量声明为 extern
的情况。除了你有全局常量的情况外,extern 关键字只适用于意大利面条式编程。如果您发现自己将变量声明为 extern/global,则表明您的程序设计非常糟糕。以上是关于什么定义了 C 中的不透明类型,它们什么时候需要和/或有用?的主要内容,如果未能解决你的问题,请参考以下文章