未知类型名称'class';您是指'Class'吗?

50
我正在尝试从SpeakHere Apple Xcode项目示例中实现AQRecorder.h类,但即使我将我的实现类重命名为扩展名为*.mm的文件并加入#import "AQRecorder.h"这一行,仍会出现错误"Unknown type name 'class'; did you mean 'Class'?"和许多其他错误。 根据我的理解,这意味着它不能被识别为C++类。
任何帮助将不胜感激。

@Zhou 已经说得很好了,我也提供了一个替代方案。 - Diziet
13个回答

49

我刚刚遇到了这个确切的问题。我有一个视图控制器,使用了AQRecorder.mm中的AQRecorder类。

当我在视图控制器中包含AQRecorder.h时,就会出现这些错误。 我认为是因为我的纯Objective-C视图控制器(以.m文件命名)包含C++头文件,编译器才会抛出虚假的错误。

有两种解决方法。 最快的方法是将包括AQRecorder.h的视图控制器类重命名为.mm文件,例如将UIRecorderViewController从.m重命名为.mm。

或者,移动以下包含内容:

#include "CAStreamBasicDescription.h"
#include "CAXException.h"

将 AQRecorder.h 移到 AQRecorder.mm 中。这意味着纯 Obj-C 代码中将不再包含(通过引用)直接的 C++ 风格头文件。

希望这样有所帮助,且易于理解。


2
如果你和我一样需要在Objective-C类中声明ivars的C++头文件,你可以使用类扩展,详见这里:http://philjordan.eu/article/mixing-objective-c-c++-and-objective-c++。 - Siobhán
@SeanD。那真是相当不错的。 - Diziet
2
你也可以在“文件检查器”中只更改文件类型为“Objective-C++源代码”。这与更改文件名扩展名为“.mm”的效果相同。 - Michael Wildermuth

21
在我的情况下,这个错误是由两个类中循环的“Import”语句引起的:每个类的头文件都包含了另一个类的头文件,导致了“未知类型名称'ClassA'; 你是指'ClassB'吗?”错误:

enter image description here

这就是当我遇到这个错误时我的导入声明配置情况。在ClassA.h中:

Import "ClassB.h"

ClassB.h文件中:

Import "ClassA.h"
为了修复它,我使用了@class前向声明指令在ClassB.h中前向声明了ClassA(这个指令告诉预编译器ClassA是一个有效的类,并且在编译时会可用)。例如:
在ClassA.h中:
Import "ClassB.h"

ClassB.h中:

@class ClassA;

这修复了未知类型名称 'ClassA'的错误,但也引入了新的错误:ClassB.m实例消息的接收器类型 'ClassA'是一个向前声明。 例如:

enter image description here

为了解决这个新错误,我不得不在ClassB(ClassB.m)的实现文件顶部导入ClassA.h。现在两个错误都已经解决,我没有任何错误和警告。

例如,现在我有:

ClassA.h中:

Import "ClassB.h"

ClassB.h 文件中:

@class ClassA;

ClassB.m文件中:

Import "ClassA.h"

两个错误消息现在都已解决。


3
OP的错误字面上是Unknown type name 'class'; did you mean 'Class'?。换句话说,它似乎将他的C++头文件解释为Obj-C头文件而不是Obj-C++头文件。 - Lily Ballard
啊,我懂了。谢谢你的帮助。我遇到的错误实际上是“Unknown type name 'JKJobVC'; did you mean 'JKJobDC'?”(其中JKJobVC是一个视图控制器,JKJobDC是一个数据控制器)。我的回答包含了我解决这个问题所执行的步骤。我已经编辑了答案,包括截图并提高了整体清晰度。如果OP的错误信息是字面意思,我的答案可能完全不对,但我确信它可以帮助其他遇到类似我遇到的“Unknown type name ''; did you mean ''?”错误的人们。 - Steve HHH
我遇到了与问题相同的错误,这个答案解决了我的问题。 - hatunike
这是一个不同的错误信息和不同的问题。 - Steve Waddicor

8
我跟你遇到了相同的错误,希望我的解决方案能帮到你。Xcode编译器能够编译 "*.mm" 文件中的 objective-c 和 c++ 代码,因此你可以将导入 "AQRecorder.h"(所有直接或间接) 的文件名都改为 ".mm" 后缀。但你可能不想这么做,你可能发现 SpeakHereController 和 SpeakHereViewController 之间的关系有些棘手,我刚学会了他是如何使用的,通过在一个 nib 文件中创建 SpeakHereController 对象,所以 SpeakHereViewController 文件不必导入 "AQRecorder.h" 文件。我的英语很蠢,但我希望我的答案能对你有所帮助。

刚刚意识到你说的话基本上就是我刚写的。有道理! - Diziet
嘿,周,我是北京的iOS程序员,在stackoverflow上见到你很高兴,希望能和你交个朋友。 - DJean
哈哈,@DJean 很高兴~~ - Zhou

3

重要提示:在编译器设置中选择“编译源代码为”变量,并将其值设置为“Objective-C ++”。


如何使用终端从clang设置此变量? - mbaros
@mbaros 反过来。这个变量告诉Xcode将一个参数传递给Clang命令行。 - Ky -
嗨,要在哪里修改“编译源代码为”? - famfamfam
构建设置 -> Apple-Clang 语言 -> 编译源代码为 - Anonimys

2

看起来这个问题似乎无法解决。 如果可以将 #include "myC++.h" 移到 *.mm 文件中,则可以解决该问题。 但是,如果您需要从 objectiveC.h 文件中使用它,则会失败。 我猜这是苹果公司的一个错误。有一种方法可以指定 *.mm 而不是 *.m, 但没有类似于 *.hh 而不是 *.h 的东西。


8
我想我已经找到了解决方案。在项目选项中,在“Apple LLVM编译器3.1-语言”设置组中,将“编译源代码为”选项更改为“Objective-C ++”。我认为这会使编译器始终假定为C++,而不考虑文件扩展名。 - chicha
@peetonn 我不知道为什么SpeakHere可以工作,但是在新项目中所有的源文件都无法工作。我已经检查了所有的构建设置,并且让它们相同,但是没有成功:-( 然而,将编译源文件设置为Objective-C++确实有效。 - Ben Clayton
将“编译源代码为Objective-C++”解决了我所有的问题。我认为这只是Xcode 4.1到4.2的普遍失误... http://philjordan.eu/article/mixing-objective-c-c++-and-objective-c++ - jocull

1
我今天解决了这个问题。如果你在YourHeader.h中#include或#import一个C++ *.h文件或C++/OC混合*.h文件,那么你必须有一个YourHeader.mm文件。否则,所有的C++文件和C++/OC混合文件都会显示编译错误。

1
那不正确,问题是因为您混合使用了Objective-C和C++,而一些在C++中使用的保留字在ObjC中无法识别。下面Sean-D提供了一些好建议和有效的解决方案。 - pocjoc

0

具体来说,如果您正在编译NDK C/C++代码,并且出现以下错误:

Unknown type name 'jclass'; did you mean 'class'?

很可能包含“jclass”的文件被直接或间接地#include在将要构建为库的.c/.cpp文件中。解决方法是:删除该#include


0

从我的经验来看,需要注意以下几点:

  1. 在编译器设置中选择“编译源代码为”变量,并将其值设置为“Objective-C++”,即Build Settings->Apple LLVM 5.1 - Language->Compile Source As->Objective-C++(在Xcode 5.1.1中)。

  2. 将包含C++头文件的相关文件从.m更改为.mm(有时需要将所有.m更改为.mm)。这是由@Diziet回答的。

  3. 如果遇到不兼容类型错误,请显式地进行所需类型的类型转换。当它是.m文件时,这些错误可能不会显示出来。


0
这个问题可以通过更改以下构建设置来解决:
在Apple LLVM Compiler 4.2 - Language下
C++语言方言(Gnu++11适合我) C++标准库(libxc++适合我)
如果您让Xcode使用文件扩展名来决定如何编译每个文件,则还需要将.m文件命名为.mm。

0
我通过以下方式解决了这个问题:
最初,文件被放置在项目内,但不是在正确的文件结构内。
是的,我知道它并不是实际的结构,因为它只是用于视觉问题,但当我将头文件和 CPP 文件移动到 PROJ 文件夹内时,一切都正常工作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接