Mik*_*our 25
你不能.标准只是声明FILE"能够记录控制流所需的所有信息的对象类型"; 这是由实现这是否是typedef的struct(他的名字你不知道反正),或别的东西.
声明的唯一可移植方式FILE是#include <stdio.h>(或<cstdio>在C++中).
cHa*_*Hao 11
如果你#include <stdio.h>应该得到FILEtypedef.这是唯一真正安全且可移植的方式 - 你不能没有类型别名的typedef,并且不能保证FILE别名是什么类型,所以每个编译器或libc或其他什么都可以有不同的别名.但是,如果有人真正想要#include <stdio.h>,你需要这种类型是正确的,以免不一致的定义导致错误.
编辑:
现在我想起来,可能还有另一种我能想到的方式.它不是一个typedef,它是通过劫持"FILE"定义而起作用的邪恶宏观内容.我不会仅仅因为这个原因而推荐它.但它可能适合您的需要.
#ifdef USES_REAL_FILE_TYPE
#include <stdio.h>
#else
#define FILE void
#endif
/* declare your struct here */
#ifndef USES_REAL_FILE_TYPE
#undef FILE
#endif
Run Code Online (Sandbox Code Playgroud)
然后#define USES_REAL_FILE_TYPE在将文件包含在需要实际的任何代码中之前FILE *,其余的代码只会将指针视为a void *.
我不保证这不会弄乱东西.特别是,在任何你想知道关于这种假类型的真实内容的情况下它会破坏,并且所有触及指针的代码都可能需要#define.但是,如果你已经死定了"不必要的"#includes,那么这是你唯一可以在FILE *不干扰stdio 的情况下获得的.你无法转发声明typedef.
EDIT2:
好的,我检查确认.不确定它是多么标准,或者你可以用它做什么,但......
typedef FILE;
Run Code Online (Sandbox Code Playgroud)
在Visual C和GCC中都有效,但仅在编译C代码时才有效.似乎C++标准明确地说某个地方没有类型就没有typedef.然而,C一个没有.
但是,它似乎不允许向前声明类型,而不是在GCC中.如果你typedef int FILE;之后尝试,它会引发有关冲突的typedef的错误.然而,VS似乎允许它,只要它是一个整数类型.看起来typedef X确实意味着typedef int XVS(显然,在C99中).无论哪种方式,GCC都不会让你重做typedef,即使是完全相同的类型.
FILE 是一个你不应该过多探索的结构的typedef(比如你不应该使用WinAPI句柄背后的数据),除非通过它的专用API函数.
正向声明允许一个人声明一个指针(或C++,一个引用)到该类型,并且只要不使用该符号就编译该声明(例如,在标题中向前声明一个符号,然后包括标头在使用它的源中正确声明的标头).
因此,前向声明包括:
typedef的问题在于它们很难处理,因为正如您所发现的那样,您无法前向声明它们.
所以你不能转发声明FILE,也不能转发声明std::string.所以你别无选择,只能包含标题来处理它们.
(这就是我讨厌struct { /* ... */ } MyTypedefedType ;C入侵C++代码中的typedef 模式的原因:它在C++中没用,它阻止了前向声明.)
好的部分是,如果符号是"标准",那么包含它们的标题不应该太痛苦.耦合并没有那么多问题,如果它会稍微减慢编译速度,即使通过使用预编译头文件也可以轻松实现.
<iosfwd> :有人在想你!C++标准库提供<iosfwd>标头.
<iosfwd>如果你需要的只是前向声明,你可以包括,而不是包括任何(或所有)C++流标题.