我们的教授为我们提供了复数程序的两个版本:DT版本和ADT版本。
DT版本与ADT有很多不同,但是我不能理解的是,结构声明的放置位置是否重要
。在DT版本中,结构声明和函数声明一起放在标头中;在ADT版本中,它已放置在.c文件中,即编写函数的位置。
放置结构的位置重要吗?从我的想象中,它可以以任何一种方式起作用,但是我不确定,因为我才刚开始使用整个ADT概念。我看不到该结构所放置的文件如何会破坏信息隐藏。
答案 0 :(得分:0)
第二个版本(ADT)在其他翻译单元中将不可见。因此,如果在某些翻译单元中需要引用结构的完整定义,则编译器将发出错误。
在DT的实现中,似乎对应的功能引用了ADT。因此,仅在处理ADT的功能中需要ADT的定义。在这种情况下,没有任何问题。
通常,使用这种方法时,会使用内部链接将ADT定义的功能声明为静态。 DT的功能在内部调用ADT的功能。
这是ADT的定义及其功能被隐藏,并且仅对于引用ADT及其功能的DT功能定义可见。
答案 1 :(得分:0)
如果在头文件中声明了类型的字段,则客户端可以访问和修改这些字段,而无需通过提供模块接口的函数。抽象数据类型的目的之一是能够在不影响客户端模块的情况下更改实现(例如数据表示形式)。
答案 2 :(得分:0)
放置结构的位置重要吗?
如果您的程序不使用任何设计,而您只是“砍掉”,那么这无关紧要。否则,如果您的程序较大且专业,那么对于私有封装而言,它就很重要,这是面向对象设计中使用的一个关键术语。
如果将结构定义放在头文件中,则使用该结构的代码可以访问结构成员,这是完全公开的。
如果仅在头文件中放置结构的前向声明,但在.c文件中放置实际的结构定义,则可以实现私有封装。只有.c文件可以访问该结构的内容。这通常称为不透明类型。
这又意味着调用者将无法声明该结构的对象,因为该定义对于调用者而言是不可见的。但是,他们可以声明一个指向这种结构的指针。
简单的例子:
foo.h
typedef struct foo foo;
foo* foo_init (int x);
void foo_free (foo* f);
int foo_get_x (const foo* f);
foo.c
#include "foo.h"
struct foo
{
int x;
};
foo* foo_init (int x)
{
foo* f = malloc(sizeof *obj);
f->x = x;
return f;
}
void foo_free (foo* f)
{
free(f);
}
int foo_get_x (const foo* f)
{
return f->x;
}
caller.c
#include "foo.h"
foo* f = foo_init(123);
printf("%d", foo_get_x(f));
foo_free(f);