转发在Objective-C中声明一个结构
我正在创建一个协议,我正在定义的方法的一个参数是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命名空间
- 结构的声明
- 避免多个标签定义
struct t_mon_struct;
是标记结构的前向声明。 具体来说,它的名称存在于struct namespace中。
存在于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
绑定到struct命名空间中的匿名结构,除非其声明可见,否则不能引用它。
有CMTime
宣布:
typedef struct CMTime { CMTimeValue value; CMTimeScale timescale; CMTimeFlags flags; CMTimeEpoch epoch; } CMTime;
那么你可以通过使用前向声明struct CMTime
:
struct CMTime; void foo(struct CMTime*);
由于它没有这样声明,你需要#include
它的声明,或设计一个解决方法。
当struct的typedef与其标签不同时,复杂性会恶化。 您无法绑定或重新声明typedef(在C中)。 但是,您可以使用struct命名空间中的名称来隐藏它 – 一些库作者认为这是私有的。
只需在struct之前添加typedef
就可以了。
typedef struct CMTime;
如果您希望具有前向声明的文件知道结构的内容,则需要导入一个标头(可以在多个位置)定义它的位置。 如果您不需要访问其属性,则可以转发声明结构,但这是它的范围。