转发在Objective-C中声明一个结构

时间:2012-02-02 21:50:19

标签: objective-c c struct forward declare

我正在创建一个协议,我正在定义的方法的一个参数是CMTime*。我想转发声明CMTime而不是包括它。但是,我已经尝试了@class CMTime并且它抱怨它在别处被重新定义为不同类型的符号。文档说这是一个结构。我已经尝试将其声明为

struct CMTime;

但仍抱怨它不知道它是什么。

任何想法我做错了什么?

3 个答案:

答案 0 :(得分:18)

编译为ObjC的源在这方面与C具有相同的规则。

编译为ObjC ++的源在这方面与C ++具有相同的规则。

@class MONClass;是ObjC类型的前向声明。不要将它用于结构。

struct t_mon_struct;名为 C或C ++结构的前向声明。不要将它用于ObjC类型。从技术上讲,编译器允许您将C ++类声明为结构(当然,该类也在全局命名空间中声明)。

因此,语义的根源都归结为C(假设这是一个ObjC转换)。我现在不再提及ObjC和C ++了。

这里有一些常见的复杂因素:

  • struct namespace
  • 结构的声明
  • 避免多个标签定义

struct t_mon_struct;是标记结构的前向声明。具体来说,它的名称存在于struct namespace中。

存在于struct namespace中的标记结构:

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命名空间中的名称来隐藏它 - 一些库作者认为这是私有的。

答案 1 :(得分:1)

只需在结构之前添加typedef即可。

typedef struct CMTime;

答案 2 :(得分:0)

如果您希望具有前向声明的文件知道结构的内容,则需要在其中定义标头(可以在多个位置)。如果您不需要访问其属性,可以转发声明结构,但这是它的范围。