[这是我于1997年9月23日发送给一位索要示例的人的邮件摘录。]

发件人:scs@eskimo.com (Steve Summit)
主题:回复:ADT??
日期:1997年9月23日,星期二,18:21:38 -0700 (PDT)
Message-Id:<199709240121.SAA03216@mail.eskimo.com>

...你可能在adt.h中有声明

	extern struct adt *newadt(void);
	extern int processadt(struct adt *);
	extern void freeadt(struct adt *);

然后一个客户端可以这样做

	#include "adt.h"
	struct adt *theadt = newadt();
	processadt(theadt);
	freeadt(theadt);

ADT的实际实现将从这里开始

	#include "adt.h"
	struct adt
		{
		/* actual structure definition */
		};

	struct adt *
	newadt(void)
	{
	...

或者,如果ADT的实现包含多个源文件,你可以将结构体定义放在,例如,adtinternals.h:

	struct adt
		{
		/* actual structure definition */
		};

然后,包含这两个文件adt.hadtinternals.h在实现ADT的每个源文件中

	#include "adt.h"
	#include "adtinternals.h"

	struct adt *
	newadt(void)
	{
	...

有时,我发现将与ADT相关的所有声明集中在一个头文件中(“adt.h”,在继续的示例中),这样做是这样的

	#ifdef ADT_INTERNALS
	struct adt
		{
		/* actual structure definition */
		};

	#endif

	extern struct adt *newadt(void);
	extern int processadt(struct adt *);
	extern void freeadt(struct adt *);

然后我定义ADT_INTERNALS在实现ADT的每个源文件中,就在包含adt.h:

	#define ADT_INTERNALS
	#include "adt.h"

	struct adt *
	newadt(void)
	{
	...

这显然是一种较弱的信息隐藏形式,因为客户端更容易“作弊”并窥探类型的实现。

最后,当你使用第一种形式,即不完整的结构体类型时,通常将不完整的结构体声明放在公共头文件中是很有用的

	struct adt;
	extern struct adt *newadt(void);
	extern int processadt(struct adt *);
	extern void freeadt(struct adt *);

这可以防止某些编译器警告,并避免其他一些晦涩的潜在问题。