C++/CLI の特徴

理由あって数日前から VS2005 を使い始めていますが、やはりジェネリクスは便利だと思いました。特に ArrayList や Hashtable などでは有効で、是非 List<T> および Dictionary<T> に書き換えることを推奨します。手間はかかりますが、それに見合うだけのパフォーマンス向上などのメリットがあります。他には、あまり使わないかも知れませんが、NULL 許容型という概念が導入されたことを挙げておきます。これは簡単に言えば、Int32 などの値型に、それが実際に有効であるかどうかのフラグを付加したようなものです。

VS2003 から 2005 へのバージョン アップで、最も大きな進化を遂げたのは VC++ でしょう。前回の Managed C++ が、名前のとおり、従来の C++ を CLI に対応させた(だけ)だったのに対し、今回の C++/CLI では CLI が中心に据えられています。ちなみに前回は、__(アンダースコア)で始まるキーワードが多かったのですが、今回はその殆どがアンダースコア無しになっています。つまり、マイクロソフトの独自拡張ではなくなったということです。

今回、特に大きく変更されたのはリソースの解放に関する機構で、なんと IDisposable が暗黙的に実装されるようになっています。これは他の言語にはない、C++/CLI の独自仕様です。IDisposable.Dispose() はコンパイラによって自動的に定義されます。定義の詳細は不明ですが、結局はそのクラスの「デストラクタ」と呼ばれるメソッドが呼び出されるようになっています。デストラクタは、マネージ リソースとアンマネージ リソースの両方を解放するためのメソッドです(プログラマが実装します)。つまり従来の意味での Dispose() に相当します。C++/CLI でデストラクタを呼び出すには、Dispose() を呼び出すのでなく、直接その名前を指定するか delete を適用します。他の言語からでは、Dispose() を呼び出す方法しかありません。

さらにもうひとつ。ネイティブの C++ においては、スタック上にインスタンスを生成した場合、その関数が終了すると自動的にデストラクタが呼び出されます。これと同等のことが C++/CLI でサポートされています。ただ、これは構文上の話であって、実際にはコンパイラが gcnew の挿入や Dispose() の呼び出し等を行なっています。

リソース管理以外の点では、^ 記号が導入されたということを挙げておきます。これは「マネージ ヒープにあるオブジェクトに対するハンドル」という意味で、Managed C++ で言うところの __gc* です。記号が真横でなく右上にあるというのは、慣れるまでちょっと見づらい気もしますが、ポインタとの区別をつけるという意味では賛成です(この記号を導入するに到るまでの経緯については、MSDN ライブラリに記事がありますのでご覧下さい)。ちなみに Object の配列を保持する変数を宣言する場合、array<Object^>^ となります。この array も、新たなキーワードです。

以上のように、C++/CLI は、マネージ拡張において「拡張」の扱いを受けていた部分が標準化され、さらにネイティブ C++ の良いところが上手く導入されたものになっています。