推荐的方法是将c++类应用到Objective-C类中,尽量减少使用objective - c++ ?

时间:2022-09-07 07:58:47

I'm mixing Objective-C and C++. However I want to minimize using of Objective-C++. Because it has some kind of limits in both of Objective-C and C++.

我混合了Objective-C和c++。但是我想最小化使用objective - 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 C.h in B.h, but if I did it, B.h cannot be imported into A.h. So I have to leave variable c as void* type. This is not a big problem because I can use members of C in B.m file freely. But I always have to cast it. This feels something unclear. So I want to use better way if it is.

我想包括C。在B h。h,但是如果我这么做了,B。h不能导入到A.h中,所以我必须保留变量c为void*类型。这不是一个大问题,因为我可以在B中使用C的元素。*m文件。但我总是要投。这个感觉不清楚的东西。我想用更好的方法。

2 个解决方案

#1


15  

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++. Make the headers pure Objective-C and pure C++, with pointers to a forward-declared struct containing the actual implementation. This is defined in the .mm file, and can then use Objective-C++.

有几种方法可以做到这一点,但在我看来,最好的方法是使用“PIMPL”习语,这在c++中相当常见。使header纯Objective-C和纯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/ strategy -for use -c+ in-objective-c-projects -它还展示了一些其他的方法,包括您最初的void*方法。

#2


4  

As pmjordan wrote in his blog article, BImpl within @interface declaration needs 'struct' keyword as follows.

正如pmjordan在他的博客文章中所写,@interface declaration中的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. The added 'struct' keyword causes Objective-C compiler to understand this header as pure C for other .m files which import this header. Otherwise other *.m files which import this header won't be compiled. This small solution saves you from changing the *.m files to .mm files. Sometimes, changing original .m files to .mm causes a lot of compile errors.

我认为他无意中漏掉了这个。如果你需要包含这个标题,当你有很多*。m文件,这有很大的不同。添加的“struct”关键字会导致Objective-C编译器将这个头文件理解为纯C。否则其他*。导入该头的m文件不会被编译。这个小的解决方案可以避免您更改*。m文件到.mm文件。有时,将原始的.m文件更改为.mm会导致很多编译错误。

#1


15  

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++. Make the headers pure Objective-C and pure C++, with pointers to a forward-declared struct containing the actual implementation. This is defined in the .mm file, and can then use Objective-C++.

有几种方法可以做到这一点,但在我看来,最好的方法是使用“PIMPL”习语,这在c++中相当常见。使header纯Objective-C和纯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/ strategy -for use -c+ in-objective-c-projects -它还展示了一些其他的方法,包括您最初的void*方法。

#2


4  

As pmjordan wrote in his blog article, BImpl within @interface declaration needs 'struct' keyword as follows.

正如pmjordan在他的博客文章中所写,@interface declaration中的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. The added 'struct' keyword causes Objective-C compiler to understand this header as pure C for other .m files which import this header. Otherwise other *.m files which import this header won't be compiled. This small solution saves you from changing the *.m files to .mm files. Sometimes, changing original .m files to .mm causes a lot of compile errors.

我认为他无意中漏掉了这个。如果你需要包含这个标题,当你有很多*。m文件,这有很大的不同。添加的“struct”关键字会导致Objective-C编译器将这个头文件理解为纯C。否则其他*。导入该头的m文件不会被编译。这个小的解决方案可以避免您更改*。m文件到.mm文件。有时,将原始的.m文件更改为.mm会导致很多编译错误。