我正在创建一个协议,其中我定义的一个方法的参数是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 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与其标记不同时,问题会变得更加复杂。在C语言中,您不能绑定到或重新声明typedef。但是,您可以通过在结构体命名空间中使用名称来绕过它 - 这被一些库作者视为私有内容。
在结构体之前加上typedef
对我来说就可以了。
typedef struct CMTime;
如果您想让具有前向声明的文件了解结构体的内容,它们需要导入定义该结构体的头文件(可以在多个位置)。如果您不需要访问其属性,则可以前向声明结构体,但仅限于此。
CMTime
的声明方式,我认为这已经算是一个具体的答案了。 - justinstruct
标签。void foo(CMTime*)
与void foo(struct CMTime*)
的区别。 - justin