14

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

struct CMTime;

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

任何想法我做错了什么?

4

3 回答 3

18

在这方面,编译为 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 命名空间中的名称来绕过它——一些库作者认为这是私有的。

于 2012-02-02T22:48:03.547 回答
1

只需typedef在结构之前添加就可以了。

typedef struct CMTime;
于 2015-03-11T14:23:42.297 回答
0

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

于 2012-02-02T22:09:24.203 回答