5

Objective-C と C++ を混在させる必要があります。すべての C++ を 1 つのクラス内に隠し、他のすべてをプレーンな Objective-C のままにしたいと考えています。問題は、いくつかの C++ クラスをインスタンス変数として使用したいということです。これは、他のクラスによってインクルードされるヘッダー ファイルで言及する必要があることを意味し、C++ はアプリケーション全体に広がり始めます。これまでのところ、私ができる最善の解決策は次のようになります。

#ifdef __cplusplus
#import "cppheader.h"
#endif

@interface Foo : NSObject
{
    id regularObjectiveCProperty;
    #ifdef __cplusplus
    CPPClass cppStuff;
    #endif
}

@end

これは機能します。実装ファイルにはmm拡張子があり、C++ と混合された Objective-C としてコンパイルされ、C++ の#ifdefロックが解除されます。他の純粋に Objective-C のクラスがヘッダーをインポートすると、C++ のものは隠され、クラスは特別なものを認識しません。これはハックのように見えますが、より良い解決策はありますか?

4

5 に答える 5

8

これは、interface/@protocol の古典的な使い方のように思えます。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、これらのクライアントに のインスタンスを渡すことができます。

于 2009-06-29T15:25:54.607 に答える
3

私も最近この問題に遭遇しました。私の場合、プロトコルはやり過ぎでした。たまたま C++ オブジェクトだったデータ アクセス オブジェクトへのポインタを保持する必要がありました。

私がしたことは、void *インスタンス変数を使用してクラスを宣言し、インスタンス メソッドで使用するときにそれをキャストすることでした。

これはちょっとハックっぽいですが、概念的には、Objective-Cid型と非常によく似ています。

于 2009-10-29T15:03:33.233 に答える
1

すべてにObjectiveC++を使用できない特別な理由はありますか?コンパイラをCompileSourcesAs:Objective C ++に切り替えるだけです(または、すべてのソースファイルの名前を.cppまたは.mから.mmに変更します)。次に、C++とObjectiveCを自由に組み合わせることができます。

C++はアプリケーション全体に広がり始めます

それにはどのような問題がありますか?ObjectiveCコードが一般的にC/Objective Cコードのみを実行している場合、C++としてコンパイルされてもほとんど影響を受けません。サイズや速度のパフォーマンスに大きな問題はありません。

私が見つけた唯一の2つの欠点は、次のとおりです。Clang静的アナライザーを使用してC++を分析することは(まだ)できません。一部の(比較的奇妙な)CコードはC ++で機能しません。これは、サードパーティのCコードを使用するときに問題になることがあります。

于 2009-06-30T06:13:36.877 に答える
0

これを行うと問題があることに気付くかもしれません.ObjectiveC++について私が覚えていることから、囲まれたC++オブジェクトのコンストラクターとデストラクタが呼び出されないことに気付くかもしれません.

于 2009-07-28T12:50:42.927 に答える
0

こんなことしないで

インスタンス変数を ifdef すると、このクラスの 2 つの個別のインスタンス変数レイアウトが得られます。半分のケースでオブジェクトに割り当てられたメモリが短すぎるため、ランダムなメモリスマッシャーがいたるところに発生します。インスタンス変数を ifdefing する代わりに、その型を次のように前方宣言します。

struct CPPClass;

そしてivarにそれへのポインタを持ってから、init/deallocメソッドでnew/deleteを呼び出してオブジェクトを作成します。複数のオブジェクトがある場合は、すべての C++ ivar を直接保持する構造体を作成してから、その構造体を新規作成/削除することができます。

ObjC++ について詳しく説明しているポッドキャストを含む、詳細と情報へのリンクについては、このスレッドを参照してください: Can I separate C++ main function and classes from Objective-C and/or C routines at compile and link?

于 2015-02-12T11:10:28.040 に答える