›Objective-C【Objective-C++】NSObjectラッパークラスで快適コーディングを実現するObjective-CのオブジェクトをC++のクラスでラップすることで、==による比較処理やa.equals(b)形式によるメソッド呼び出し式を実現することができます。今回紹介するテクニックによって、Java言語やSwift言語のような簡潔な記述や高い開発効率を実現することが可能になります。基本ラッパークラス実装方法は以下の通りです。ns_basic_objectは基本クラスです。実際にはns_basic_objectを継承したクラスをObjective-Cオブジェクト毎に作成して利用します。ns_objectがその継承例です。ns_basic_object<NSObject*>::ns_basic_object;};Objective-CオブジェクトからC++オブジェクトへの変換は暗黙的に行われます。1C++の機能により、比較演算子==による比較や、.記法よるメソッド呼び出しを実現することが可能になりました。isEqual:obj])による呼び出しにも対応しています。C++オブジェクトからObjective-Cオブジェクトへの暗黙的な変換も可能です。比較演算子を有効にするには、必要に応じて==と!=の行をコメントアウトします。ポインタ比較が行えなくなるため注意が必要です。ラッパークラス先程定義した基本ラッパークラス(ns_basic_object)を継承することで、NSObject以外の様々な型に対応することもできます。以下はNSStringに対応したns_stringクラスの例です。substringFromIndex:0])の利用も可能です。ラッパークラスはObjective-Cオブジェクトとの互換性があるため、既存の型を一括でラッパクラスに置き換えても、既存のコードはそのまま機能することになります。*にStringという別名を付けていたため、移行は比較的容易に行えました。}ns_stringを活用する場合には、今後のリファクタリングの手間を考慮して型の別名を活用することをオススメします。}参考までに、C++の世界ではtypedefの代わりにusingが使われます。NSStringのオートボクシングを実現するNSStringの特性や変換コストを考えると、あまりオススメはできませんが、C言語スタイル文字列に対するオートボクシングの実現も可能です。s))を先程のns_stringクラスに追加することで、文字列リテラルからの初期化に対応することができます。string.length());これによって、Java言語と同等の記述が実現できるようになりました。}};基本型への暗黙変換は抑制しています。9)が行えるようになります。実際には名前空間を用いて以下のような運用を行うと良いでしょう。親クラスの定義を小クラス側で再利用するための技法も紹介しておきます。テンプレート機能でこれを実現します。}};最適化と値渡し以下の関数は、最適化が働くと、いずれも同一の実行コードに変換されます。ポインタ渡し(ObjC生オブジェクト)メソッドの場合も同じです、ラッパークラスの内部ポインタのみがポインタ渡しされます。sと宣言した場合と同一の実行コードに変換されるということです。最適化が行われなかった場合やデバッグビルド時には、値渡しは余計なコンストラクタ呼び出しやデストラクタ呼び出しを引き起こすため、値渡しの利用はオススメできません。代わりに、参照渡しとObjective-Cオブジェクトのポインタ渡しを上手く使い分けることで、上記の問題を回避することができます。@"b");}本イディオムの目的Objective-CのオブジェクトをC++のクラスでラップする本テクニックは、Objective-CやCocoaフレームワークの冗長的な記述を回避する目的に利用できる他、C++製の既存フレームワークやテンプレートライブラリの資産を活用する目的にも利用できます。以下のC++標準文字列クラス(std::string)向けに作られた既存のテンプレート関数(print_string)は、今回作成したns_stringにも適用することができます。互換性ありstd::stringのメンバ関数c_strと同名のメンバ関数がns_string側に定義されているため、ns_stringはstd::stringと一部共通のインターフェースを持っているとみなされます。このように、本イディオムは、既存のコードやロジックを再利用する目的としても活用できます。end関数の多重定義や演算子オーバロードを活用すれば、C++標準テンプレートライブラリのアルゴリズムを活用することも可能になります。仮想テーブルについて今回紹介した基本クラスns_basic_objectではvirtualキーワードによる仮想関数の宣言を用いていません。最適化と値渡し」のゼロオーバヘッドの特性を実現する意図があります。Objective-C)を目的としています。柔軟な設計や、仮想関数を用いた抽象クラス等の設計を用いる場合には、多くのケースでは仮想デストラクタによる対処が必要となるため注意して下さい。