C ++类作为Objective-C类的实例变量

时间:2009-06-29 07:04:19

标签: c++ objective-c objective-c++

我需要混合使用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 ++的东西被隐藏起来,而且类没有看到任何特殊的东西。这看起来像黑客,有更好的解决方案吗?

5 个答案:

答案 0 :(得分:8)

这听起来像是接口/ @协议的经典用法。为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的实例传递给这些客户端。

答案 1 :(得分:3)

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

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

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

答案 2 :(得分: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代码时偶尔会出现问题。

答案 3 :(得分:0)

您可能会发现在执行此操作时遇到问题 - 从我记得的ObjectiveC ++中您可能会发现,无法调用随附的C ++对象的构造函数和析构函数。

答案 4 :(得分:0)

不要这样做

如果您确定了一个实例变量,那么将为该类提供两个单独的实例变量布局。你将获得随机内存粉碎机,因为在一半的情况下为对象分配的内存将太短。而不是ifdefing出实例变量,而是向前声明它的类型,如

struct CPPClass;

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

请参阅此主题以获取更多详细信息以及更多信息链接,包括详细讨论ObjC ++的播客:Can I separate C++ main function and classes from Objective-C and/or C routines at compile and link?