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.hB.h、入れた場合はB.hにインポートできませんA.h。したがって、変数cvoid*型として残す必要があります。Cin B.mfileのメンバーは自由に使えるので、これは大きな問題ではありません。しかし、私は常にそれをキャストする必要があります。これは何か不明瞭に感じます。ですから、もしそうならもっと良い方法を使いたいです。

4

2 に答える 2

15

これを行うにはいくつかの方法がありますが、私の意見では、C++ではかなり一般的な「PIMPL」イディオムを使用するのが最善の方法です。実際の実装を含む前方宣言された構造体へのポインターを使用して、ヘッダーを純粋な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 に答える