5

我需要混合使用 Objective-C 和 C++。我想将所有 C++ 内容隐藏在一个类中,并保持所有其他简单的 Objective-C。问题是我想要一些 C++ 类作为实例变量。这意味着它们必须在头文件中被提及,该文件被其他类包含并且 C++ 开始传播到整个应用程序。到目前为止,我能够提供的最佳解决方案如下所示:

#ifdef __cplusplus
#import "cppheader.h"
#endif

@interface Foo : NSObject
{
    id regularObjectiveCProperty;
    #ifdef __cplusplus
    CPPClass cppStuff;
    #endif
}

@end

这行得通。实现文件有一个mm扩展名,因此它被编译为与 C++ 混合的 Objective-C,#ifdef解锁 C++ 的东西,然后我们开始了。当其他一些纯 Objective-C 类导入标头时,C++ 内容被隐藏,并且该类看不到任何特殊内容。这看起来像一个黑客,有更好的解决方案吗?

4

5 回答 5

8

这听起来像是接口/@protocol 的经典用法。为 API 定义一个 Objective-C 协议,然后使用您的 Objective-C++ 类提供该协议的实现。这样客户端只需要知道协议而不是实现的头部。所以给定原来的实现

@interface Foo : NSObject
{
    id regularObjectiveCProperty;
    CPPClass cppStuff;

}

@end

我会定义一个协议

//Extending the NSObject protocol gives the NSObject
// protocol methods. If not all implementations are
// descended from NSObject, skip this.
@protocol IFoo <NSObject>

// Foo methods here
@end

并将原始Foo声明修改为

@interface Foo : NSObject <IFoo>
{
    id regularObjectiveCProperty;
    CPPClass cppStuff;
}

@end

然后客户端代码可以使用类型id<IFoo>,并且不需要编译为 Objective-C++。显然,您可以将一个实例传递Foo给这些客户端。

于 2009-06-29T15:25:54.607 回答
3

我最近也遇到了这个问题。在我的情况下,协议是矫枉过正的。我只需要保留一个指向恰好是 C++ 对象的数据访问对象的指针。

我所做的是用void *实例变量声明该类,并在我在实例方法中使用它时对其进行转换。

这有点 hack-y,但从概念上讲,它与 Objective-Cid类型非常相似。

于 2009-10-29T15:03:33.233 回答
1

有什么特别的原因你不能只使用Objective C++吗?只需将编译器切换到 Compile Sources As: Objective C++(或将所有源文件从 .cpp 或 .m 重命名为 .mm)。然后你可以自由地混合你的 C++ 和 Objective C。

C++ 开始传播到整个应用程序

这有什么问题?如果您的 Objective C 代码通常只执行 C/Objective C 代码,那么几乎可以肯定它不会因为被编译为 C++ 而受到影响。没有明显的大小或速度性能问题。

我发现的唯一两个缺点是:你不能(还)使用 clang 静态分析器来分析 C++;一些(相对奇怪的)C 代码不能在 C++ 中工作,这在使用第三方 C 代码时偶尔会出现问题。

于 2009-06-30T06:13:36.877 回答
0

您可能会发现这样做有问题——根据我对 ObjectiveC++ 的记忆,您可能会发现封闭的 C++ 对象的构造函数和析构函数不会被调用。

于 2009-07-28T12:50:42.927 回答
0

不要这样做

如果你 ifdef 出一个实例变量,那将为这个类提供两个单独的实例变量布局。你会在各处得到随机内存粉碎器,因为在一半情况下为对象分配的内存太短。而不是 ifdefing 实例变量,向前声明它的类型,如

struct CPPClass;

并在 ivar 中有一个指向它的指针,然后在你的init/dealloc方法中调用 new/delete 来创建对象。如果您有多个对象,您可以创建一个结构来直接保存所有 C++ 变量,然后只需新建/删除该结构。

有关更多详细信息和更多信息链接,请参阅此线程,包括详细讨论 ObjC++ 的播客: 我可以在编译和链接时将 C++ 主函数和类与 Objective-C 和/或 C 例程分开吗?

于 2015-02-12T11:10:28.040 回答