我正在创建一个协议,我正在定义的方法的参数之一是CMTime*
. 我想转发声明CMTime
而不是包含它。但是,我已经尝试过@class CMTime
,它抱怨它在其他地方被重新定义为不同类型的符号。文档说它是一个结构。我已经尝试将其声明为
struct CMTime;
但它仍然在抱怨它不知道它是什么。
任何想法我做错了什么?
我正在创建一个协议,我正在定义的方法的参数之一是CMTime*
. 我想转发声明CMTime
而不是包含它。但是,我已经尝试过@class CMTime
,它抱怨它在其他地方被重新定义为不同类型的符号。文档说它是一个结构。我已经尝试将其声明为
struct CMTime;
但它仍然在抱怨它不知道它是什么。
任何想法我做错了什么?
在这方面,编译为 ObjC 的源代码与 C 具有相同的规则。
在这方面,编译为 ObjC++ 的源代码与 C++ 具有相同的规则。
@class MONClass;
是 ObjC 类型的前向声明。不要将它用于结构。
struct t_mon_struct;
是命名C 或 C++ 结构的前向声明。不要将它用于 ObjC 类型。从技术上讲,编译器还允许您将 C++ 类前向声明为结构(当然前提是该类也在全局命名空间中声明)。
因此,语义的根源都归结为 C(假设这是一个 ObjC 翻译)。我现在将停止提及 ObjC 和 C++。
这里有一些常见的复杂性来源:
struct t_mon_struct;
是标记结构的前向声明。具体来说,它的名字存在于 struct 命名空间中。
结构命名空间中存在的标记结构:
struct t_mon_struct { int a; };
在全局命名空间中具有 typedef 的匿名结构:
typedef struct { int a; } t_mon_struct;
在全局命名空间中带有 typedef 的标记结构:
typedef struct t_mon_struct { int a; } t_mon_struct;
CMTime
声明如下:
typedef struct
{
CMTimeValue value;
CMTimeScale timescale;
CMTimeFlags flags;
CMTimeEpoch epoch;
} CMTime;
具体来说,全局 typedef 标签CMTime
绑定到结构命名空间中的匿名结构,除非其声明可见,否则可能不会被引用。
已CMTime
宣布:
typedef struct CMTime
{
CMTimeValue value;
CMTimeScale timescale;
CMTimeFlags flags;
CMTimeEpoch epoch;
} CMTime;
那么你可以通过使用前向声明得到struct CMTime
:
struct CMTime;
void foo(struct CMTime*);
由于它不是以这种方式声明的,因此您需要#include
对其进行声明,或设计一种解决方法。
当结构的 typedef 与其标记不同时,复杂性会恶化。您不能绑定或重新声明 typedef(在 C 中)。但是,您可以通过使用 struct 命名空间中的名称来绕过它——一些库作者认为这是私有的。
只需typedef
在结构之前添加就可以了。
typedef struct CMTime;
如果您希望具有前向声明的文件了解结构的内容,则它们需要导入定义它的标头(它可以在多个位置)。如果您不需要访问它的属性,您可以转发声明一个结构,但这就是它的范围。