您是用 C 还是 C++ 编码并不完全清楚。我将假设 C(所以没有重载的函数名称等)。在我看来,您需要“转发声明”您的结构。在Logger.h
中,你写:
#ifndef LOGGER_H_INCLUDED
#define LOGGER_H_INCLUDED
struct NTFS_Partition; // No details - just the name (3 times)
struct FAT16_Partition;
struct FAT32_Partition;
...
void Log_NTFS_Partition(struct NTFS_Partition *part);
void Log_FAT16_Partition(struct FAT16_Partition *part);
void Log_FAT32_Partition(struct FAT32_Partition *part);
#endif // LOGGER_H_INCLUDED
这是一般客户(的Logger.h
)需要知道的所有信息。
如果一个特定的客户端正在处理 NTFS 分区,那么它不仅会包括,Logger.h
而且NTFS.h
还会提供 的完整定义struct NTFS_Partition { ... };
,因此客户端可以创建结构的实例并用数据填充它。当然,实现日志记录的代码 ,Logger.c
也将包括Logger.h
and NTFS.h
(和FAT16.h
and FAT32.h
),因此它也可以引用结构的成员。
服务的标头(例如Logger.h
)应提供服务客户端编译所需的最少信息量。实现文件可能需要更多信息,但可以从提供它的标头中收集额外信息。
使用该struct tag
符号的一个优点恰恰是它可以根据需要经常重复,而不会弄乱任何东西。如果你没有 C11,你不能重复 a typedef
,所以如果你写:
typedef struct NTFS_Partition NTFS_Partition;
您只能包含该行一次。困难在于确保它只定义一次。为此,您可能使用头FSTypes.h
文件来定义文件系统typedefs
,该文件系统受到头文件保护的适当保护,并包含在需要任何typedefs
. 然后,您可以引用没有前面struct
关键字的类型。
如果您使用 C++ 编写代码,typedef
则不需要;struct NTFS_Partition;
声明存在这样的结构类型,并声明NTFS_Partition
为该类型的名称。如果您的代码是双语的,请使用typedef
版本;它适用于 C 和 C++。
请注意,如果您的函数例如Log_NTFS_Partition()
采用实际结构而不是指向结构的指针,那么您必须在范围内定义结构。但是,如果函数只接受指针,则前向声明就足够了。