|
|
||||||||||||||
|
| < 前ページ次ページ > |
アップルの Objective-C コンパイラでは、C++ のコードと Objective-C のコードを同じソースファイルに混在させて記述することが可能です。このような Objective-C と C++ のハイブリッド言語は、Objective-C++ と呼ばれています。Objective-C++ を使えば、Objective-C アプリケーションから既存の C++ ライブラリを利用することができます。
Objective-C++ は Objective-C のクラスに C++ の機能を追加するものではなく、C++ のクラスに Objective-C の機能を追加するものでもありません。たとえば、Objective-C 構文を使用しての C++ オブジェクトの呼び出し、Objective-C オブジェクトへのコンストラクタやデストラクタの追加、キーワードの this と self の置き換え使用などを行うことはできません。クラス階層も異なります。C++ のクラスは Objective-C のクラスを継承できませんし、Objective-C のクラスも C++ のクラスを継承することはできません。さらに、複数言語の例外処理もサポートされていません。つまり、Objective-C コードでスローされた例外は C++ コードではキャッチできず、逆に、C++ コードでスローされた例外も Objective-C コードではキャッチできません。Objective-C の例外に関する詳細については、「例外処理とスレッド同期」を参照してください。
次のセクションでは、Objective-C++ で可能なことについて説明します。
Objective-C と C++ の機能の混在
C++ の曖昧性と競合
Objective-C++ では、C++ コードと Objective-C メソッドのどちらの言語からでもメソッドを呼び出すことができます。どちらの言語でも、オブジェクトのポインタは単なるポインタであるため、どこでも使用できます。たとえば、Objective-C オブジェクトのポインタを C++ クラスのデータメンバとして含めることができ、C++ オブジェクトのポインタを Objective-C クラスのインスタンス変数として含めることができます。リスト 2-2 にこれを示します。
Objective-C インタフェースで C 構造体を宣言できるように、Objective-C インタフェースで C++ クラスを宣言することもできます。C 構造体と同様に、Objective-C インタフェースで定義した C++ クラスは、Objective-C のクラス内にネストされず、有効範囲がグローバルになります(これは、C++ ではなく、標準 C においてネストされた構造体定義の有効範囲がファイル単位になるのと同等です)。
言語に応じてコードの条件定義が行えるように、Objective-C++ コンパイラは、C++ および Objective-C 言語標準で規定されている、(それぞれ)__cplusplus と __OBJC__ プリプロセッサ定数の両方を定義します。
前述したように、Objective-C++ では Objective-C オブジェクトから C++ クラスを継承できず、C++ オブジェクトから Objective-C クラスを継承することもできません。
|
Objective-C と異なり、C++ のオブジェクトは静的に型定義されており、例外的なケースとして実行時にポリモーフィズムが利用できます。そのため、2 つの言語のオブジェクトモデルは、直接的には互換性がありません。さらに、より根本的な要素として、メモリ内における Objective-C と C++ オブジェクトのレイアウトは相互に互換性がありません。つまり、両言語に対して有効なオブジェクトインスタンスを作成するのは、一般的に不可能です。したがって、2 つのタイプの階層を混合することはできません。
Objective-C のクラス宣言の中で、C++ クラスを宣言することはできます。次のように、コンパイラは、グローバルなネームスペースで宣言されたものとして、このようなクラスを処理します。
|
Objective-C では、(Objective-C 宣言の中で宣言されたかどうかに関係なく)C 構造体をインスタンス変数として使用できます。
|
Objective-C++ も同様に、C++ クラスインスタンスをインスタンス変数として機能させることを目指しています。該当する C++ クラス(およびそのスーパークラスすべて)が仮想メンバ関数を定義しないかぎり、これは可能です。仮想メンバ関数がある場合、当該 C++ クラスは Objective-C のインスタンス変数として機能しません。
|
C++ では、仮想関数を含むクラスの各インスタンスが、適切な仮想関数テーブルポインタを含む必要があります。しかし、Objective-C ランタイムは C++ オブジェクトモデルを知らないため、仮想関数テーブルポインタを初期化することができません。同様に、Objective-C ランタイムは、それらのオブジェクトの C++ コンストラクタまたはデストラクタに対して呼び出しを発行できません。C++ クラスにユーザ定義コのンストラクタやデストラクタがあっても、それらは呼び出されません。そのような場合、コンパイラは警告を発します。
Objective-C には、ネストされたネームスペースという概念がありません。C++ のネームスペースでは Objective-C クラスを宣言できず、Objective-C クラスでネームスペースを宣言することもできません。
Objective-C クラス、プロトコル、およびカテゴリは C++ テンプレート内で宣言できず、C++ テンプレートを Objective-C クラス、プロトコル、またはカテゴリの有効範囲内で宣言することもできません。
しかし、Objective-C クラスは、C++ テンプレートのパラメータとして使用することが可能です。また、Objective-C メッセージ式では、C++ テンプレートのパラメータを(セレクタとしてではなく)レシーバまたはパラメータとして使用することもできます。
すべての Objective-C プログラムがインクルードする必要のある Objective-C ヘッダファイルには、いくつかの識別子が定義されています。これらの識別子は、id、Class、SEL、IMP、BOOL です。
Objective-C メソッドの内部では、コンパイラは C++ のキーワード this と同様に、識別子 self と super を事前宣言します。しかし、C++ のキーワード this とは異なり、self と super はコンテキスト依存であるため、Objective-C メソッドの外部でも通常の識別子として使用できます。
プロトコル内のメソッドのパラメータリストには、さらに 5 つのコンテキスト依存キーワードがあります(oneway、in、out、inout、bycopy)。これらは、他のコンテキストではキーワードになりません。
Objective-C プログラマの観点からすると、C++ には新しいキーワードがかなり追加されています。それでも C++ キーワードは Objective-C セレクタの一部として使用できるため、影響はそれほど大きくありません。しかし、Objective-C クラスやインスタンス変数の指定に C++ キーワードを使用することはできません。たとえば、class が C++ キーワードであったとしても、依然として NSObject メソッド class を使用できます。
|
ただし、これはキーワードであるため、class を変数名として使用することはできません。
|
Objective-C では、クラスとカテゴリの名前は別々のネームスペースに属します。つまり、@interface foo と @interface(foo) は、同じソースコード内に存在できます。Objective-C++ では、C++ クラスや構造体の名前と同じカテゴリを持つこともできます。
プロトコルとテンプレートの指定子は、異なる用途に同じ構文を使用します。
|
このような曖昧さを避けるために、コンパイラでは id をテンプレート名として使用することを認めていません。
最後に、次のように、ラベルの後にグローバル名を使用した式を続けた場合に、C++ の構文解釈上の曖昧さが生じます。
|
最初のコロンの後のスペースは必須です。Objective-C++ にも同様の場合があり、やはりスペースが必須です。
|
| < 前ページ次ページ > |
Last updated: 2003-09-16
製品のご購入・ご購入相談は、お気軽に アップルストアまで
0120-APPLE-1(0120-27753-1) Copyright © 2004 Apple Computer, Inc. All rights reserved. | Terms of use | Privacy Notice |