简体   繁体   English

建议将C ++类用于Objective-C类,尽量减少使用Objective-C ++?

[英]Recommended way to use C++ class into Objective-C class minimizing using of Objective-C++?

I'm mixing Objective-C and C++. 我正在混合Objective-C和C ++。 However I want to minimize using of Objective-C++. 但是我想尽量减少使用Objective-C ++。 Because it has some kind of limits in both of Objective-C and C++. 因为它在Objective-C和C ++中都有某种限制。

Currently, I'm using it like this. 目前,我正在使用它。

// A.h, Objective-C
#import "B.h"
@interface A
{
    B* b;
}
@end

// B.h, Objective-C++
@interface B
{
    void* c;
}

// C.h, C++
class C
{
};

I want to include Ch in Bh , but if I did it, Bh cannot be imported into Ah . 我想在Bh包含Ch ,但如果我这样做, Bh就无法导入到Ah So I have to leave variable c as void* type. 所以我必须将变量c保留为void*类型。 This is not a big problem because I can use members of C in Bm file freely. 这不是一个大问题,因为我可以自由地使用Bm文件中的C成员。 But I always have to cast it. 但我总是要施展它。 This feels something unclear. 这感觉不清楚。 So I want to use better way if it is. 所以如果是的话,我想用更好的方法。

There are a couple of ways of doing this, but in my opinion the best method is to use the 'PIMPL' idiom , which is fairly common in C++. 有几种方法可以做到这一点,但在我看来,最好的方法是使用'PIMPL'习惯用法 ,这在C ++中很常见。 Make the headers pure Objective-C and pure C++, with pointers to a forward-declared struct containing the actual implementation. 使标头纯粹是Objective-C和纯C ++,带有指向包含实际实现的前向声明结构的指针。 This is defined in the .mm file, and can then use Objective-C++. 这是在.mm文件中定义的,然后可以使用Objective-C ++。

In your example, you would do something like this: 在您的示例中,您将执行以下操作:

// B.h, pure Objective-C:
struct BImpl;
@interface B
{
    struct BImpl* impl;
}
// ...


// B.mm, mixed:
#include "C.h"
struct BImpl // since this is C++, it can actually have constructors/destructors
{
    C* my_c;
    BImpl() : my_c(new C) {}
    ~BImpl() { delete my_c; my_c = NULL; }
};
// make sure to alloc/initialise impl (using new) in B's init* methods,
// and free it (using delete) in the dealloc method.

I've actually written an article on solving exactly this problem, you might find it useful: http://philjordan.eu/article/strategies-for-using-c++-in-objective-c-projects - it also shows some other ways of doing it, including your original void* approach. 我实际上写了一篇关于解决这个问题的文章,你可能会发现它很有用: http//philjordan.eu/article/strategies-for-using-c++-in-objective-c-projects - 它还显示了其他一些这样做的方法,包括你原来的void*方法。

As pmjordan wrote in his blog article , BImpl within @interface declaration needs 'struct' keyword as follows. 正如pmjordan在他的博客文章中所写,@ interface声明中的BImpl需要'struct'关键字,如下所示。

struct BImpl;
@interface B
{
    struct BImpl* impl;
}

I think he inadvertently left this out. 我认为他无意中把它排除在外。 In case you need to include this header when you have a lot of *.m files, this makes a huge difference. 如果您在拥有大量* .m文件时需要包含此标头,这会产生巨大的差异。 The added 'struct' keyword causes Objective-C compiler to understand this header as pure C for other .m files which import this header. 添加的'struct'关键字使Objective-C编译器将此标头理解为导入此标头的其他.m文件的纯C。 Otherwise other *.m files which import this header won't be compiled. 否则,将不会编译导入此标头的其他* .m文件。 This small solution saves you from changing the *.m files to .mm files. 这个小巧的解决方案可以帮助您将* .m文件更改为.mm文件。 Sometimes, changing original .m files to .mm causes a lot of compile errors. 有时,将原始.m文件更改为.mm会导致大量编译错误。

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

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