您是用 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.hand NTFS.h(和FAT16.hand 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()采用实际结构而不是指向结构的指针,那么您必须在范围内定义结构。但是,如果函数只接受指针,则前向声明就足够了。