繁体   English   中英

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

[英]C++ classes as instance variables of an Objective-C class

我需要混合使用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扩展,所以它被编译为Objective-C与C ++混合, #ifdef解锁了C ++的东西,我们去了。 当其他一些纯粹的Objective-C类导入头时,C ++的东西被隐藏起来,而且类没有看到任何特殊的东西。 这看起来像一个黑客,有更好的解决方案吗?

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

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

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

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

有什么特别的原因你不能只使用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代码时偶尔会出现问题。

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

不要这样做

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

struct CPPClass;

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM