【问题标题】:Forward declare a struct in Objective-C在 Objective-C 中前向声明一个结构
【发布时间】:2012-02-25 14:11:25
【问题描述】:

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

struct CMTime;

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

任何想法我做错了什么?

【问题讨论】:

  • 不幸的是,它是使用匿名结构声明的。这意味着您要么必须复制整个声明(并希望它永远不会更改),要么只包含标题。
  • @ughoavgfhw 复制它不好(很可能,两个声明最终都在同一个 TU 中)。除此之外,我认为这是一个具体的答案,考虑到 CMTime'已声明。
  • @Justin 我只是建议它,因为他说他不会包含标题,但现在我想起来了,他在尝试创建时遇到了一个已经定义的错误一个类,这表明标题已经包含在内。如果有人可以解释,我可能会将其发布为答案。
  • @ughoavgfhw 大概是因为 OP 在使用时忘记或省略了 struct 标签。 void foo(CMTime*)void foo(struct CMTime*).
  • 你应该接受贾斯汀的回答。

标签: objective-c c struct forward declare


【解决方案1】:

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

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

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

struct t_mon_struct;named 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 命名空间中的名称来绕过它——一些库作者认为这是私有的。

【讨论】:

    【解决方案2】:

    只需在结构之前添加typedef 即可为我解决问题。

    typedef struct CMTime;
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我很抱歉(需要学习如何使用谷歌:P) - 现在编辑答案。我的答案现在正确吗?
      • 到达那里——比这更复杂。
      猜你喜欢
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 2010-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多