7

我正在混合使用 Objective-C 和 C++。但是我想尽量减少使用 Objective-C++。因为它在 Objective-C 和 C++ 中都有一些限制。

目前,我正在这样使用它。

// 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
{
};

我想包含C.h在 中B.h,但如果我这样做了,B.h则无法导入到A.h. 所以我必须将变量保留cvoid*类型。这不是一个大问题,因为我可以自由使用文件C中的成员。B.m但我总是必须投它。这感觉有些不清楚。所以如果是的话,我想用更好的方法。

4

2 回答 2

15

有几种方法可以做到这一点,但在我看来,最好的方法是使用'PIMPL' idiom,这在 C++ 中相当常见。使标头成为纯 Objective-C 和纯 C++,并带有指向包含实际实现的前向声明结构的指针。这是在 .mm 文件中定义的,然后可以使用 Objective-C++。

在您的示例中,您将执行以下操作:

// 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.

我实际上已经写了一篇关于解决这个问题的文章,你可能会发现它很有用:http: //philjordan.eu/article/strategies-for-using-c++-in-objective-c-projects - 它还显示了其他一些做这件事的方法,包括你原来的void*方法。

于 2011-03-27T10:56:02.537 回答
4

正如 pmjordan 在他的博客文章中所写,@interface 声明中的 BImpl 需要 'struct' 关键字,如下所示。

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

我认为他无意中忽略了这一点。如果您有很多 *.m 文件时需要包含此标头,这会产生很大的不同。添加的 'struct' 关键字导致 Objective-C 编译器将此标头理解为对于导入此标头的其他 .m 文件的纯 C。否则其他导入此头文件的 *.m 文件将不会被编译。这个小型解决方案使您无需将 *.m 文件更改为 .mm 文件。有时,将原始 .m 文件更改为 .mm 会导致很多编译错误。

于 2012-10-02T06:40:16.907 回答