特集Vista時代のVisual C++の流儀(後編)STL/CLRによるDocument/Viewアーキテクチャεπιστημη(えぴすてーめー)2007/05/11 |
|
|
■STL/CLRの特徴
本特集の中編ではMFCで実装されたGUIアプリケーションのDocument/Viewアーキテクチャを踏襲し、DocumentをC++/CLIで、ViewをC#で実現する手法を解説しました。その中で“できるだけネイティブなC++コードを残す”ための例として、ネイティブ・コードのSTLコンテナを、マネージ・クラス内に内包させるコードを紹介しています。
このスタイルの欠点は、マネージ・クラス内のネイティブ・メンバはポインタでなくてはならず、そのためにネイティブ・メンバの確保と解放(newとdelete)はプログラマーが責任を負わなければならないこと、さらにネイティブなコンテナはそれが管理する要素がネイティブ・オブジェクトに限られる(マネージ・オブジェクトを要素とすることができない)ためにネイティブ⇔マネージの相互変換を頻繁に行わざるを得ず、パフォーマンスを損なう恐れがあることです。
|
|
標準C++ライブラリのコンテナ(std::vectorクラス)による文字列の可変長配列 | |
マネージ・クラス内でネイティブ・メンバを使う際の欠点は、ネイティブ・オブジェクトの確保と解放が必要なこと。さらに、ネイティブ⇔マネージの相互変換を頻繁に行わざるを得ないこと。 |
STL/CLRは.NET Frameworkが提供するコンテナ群と標準C++ライブラリのコンテナ群の“合いの子”のようなライブラリです。つまりマネージ・コンテナでありながらそのインターフェイスはSTLを踏襲しています。“マネージ版STL”といってもいいでしょう。
|
|
STL/CLRのコンテナ(cliext::vectorクラス)による文字列の可変長配列 | |
マネージ・メンバであれば、確保と解放の必要がなく、ネイティブ⇔マネージの相互変換もしなくてよい。 |
STL/CLRコンテナはマネージ・クラスでありポインタを介さないので、デストラクタ/ファイナライザでdeleteする必要はありません。加えてコンテナの要素としてマネージ・オブジェクトを格納できるため、ネイティブ⇔マネージ変換を要する個所が少なくなるため、次のコード例のように実装コードの見通しがよくなります。
|
|
STL/CLRのコンテナ(cliext::vectorクラス)によりネイティブ⇔マネージ変換が不要になったコード例 |
STL/CLRが提供するコンテナと、それぞれに(機能的に)等価な.NET Frameworkコレクション(System::Collections::Generic名前空間)およびMFCテンプレート・コレクションとの対応表を以下に示します。
コレクションの種類 | STL/CLRコンテナ (cliext名前空間) |
.NET Frameworkコレクション (System::Collections::Generic 名前空間) |
MFCテンプレート・コレクション |
可変長配列 | vector<T><T> | List<T> | CArray<T> |
双方向リスト | list<T> | LinkedList<T> | CList<T> |
両端キュー | deque<T> | ||
スタック | stack<T> | Stack<T> | |
キュー | queue<T> | Queue<T> | |
優先順位キュー | priority_queue<T> | ||
ソートされた集合 (要素重複可) |
set<T> | ||
multiset<T> | |||
ソートされた辞書 (要素重複可) |
map<K,V> | SortedDictionary<K,V> | |
multimap<K,V> | |||
ハッシュ集合 (要素重複可) |
hash_set<T> | ||
hash_multiset<T> | |||
ハッシュ辞書 (要素重複可) |
hash_map<K,V> | Dictionary<K,V> | CMap<K,V> |
hash_multimap<K,V> | |||
STL/CLRが提供するコンテナと.NETやMFCのコンテナとの対応表 | |||
灰色部分は「対応するコンテナが存在しない」ことを示す。 |
このように、コンテナのバリエーションではSTL/CLRが最も多く、C++&MFCやManaged C++&.NET Frameworkで実装されたアプリケーションをC++/CLIに移植する際に、対応するコンテナに悩むことはないでしょう。
STL/CLRが提供するコンテナはマネージ・クラスでありながらジェネリック(Generic)ではなくC++のテンプレート(template)で実装されています。
テンプレートの実現メカニズムは、(.NETの)ジェネリックとは大きく異なり、コンパイル時に<>内の型が確定した時点でコード展開が行われます。template(テンプレート)はC#やVBなどの.NET言語では解釈できず、コンパイル・エラーとなります。従ってSTL/CLRはC++/CLI専用のライブラリということになります。
端的にいえば、C#では例えば、
new cliext.vector<string>()
によってSTL/CLRコンテナを生成することはできませんし、C++/CLIで生成されたアセンブリ内のメソッドからの戻り値としてSTL/CLRコンテナを返すこともできませんから、
cliext.vector<string> result = STL_CLR_lib.SomeClass.get_container();
などとやってもコンパイル・エラーとなります。
これではSTL/CLRがC++/CLI専用ということになり、いささか扱いにくいのですが、幸いなことにSTL/CLRコンテナはすべてICollection<T>インターフェイスを実装しています。なのでC++/CLI側のアセンブリ内メソッドがICollection<T>オブジェクトを戻り値に返せば、C#やVBでこれを受け取れます。また、ICollection<T>は同時にICollection/IEnumerable<T>/IEnumerableインターフェイスを継承したインターフェイスでもあるので、foreachキーワード(C#)やFor Each...Nextステートメント(VB)によってコンテナ内の要素を列挙することができます。
cliext::vector<T>クラスを例に取ると、vector<T>のクラス階層は下図のようになります。
vector<T>クラスのクラス階層 |
現行製品のVS 2005で試してみましょう。
INDEX | ||
[特集] | ||
Vista時代のVisual C++の流儀(前編) | ||
Vista到来。既存C/C++資産の.NET化を始めよう! | ||
1.Vista時代にC/C++はもはやお払い箱なのか? | ||
2.C/C++資産をどこまで生かせる? | ||
3.ネイティブ・オブジェクトをマネージ・コードでくるむ | ||
4.文字コード変換 | ||
Vista時代のVisual C++の流儀(中編) | ||
MFCから.NETへの実践的移行計画 | ||
1.C++/CLIによるWindowsフォーム・アプリケーション | ||
2.言語をまたいだDocument/Viewアーキテクチャ | ||
3..NET移行前のMFCサンプル・アプリケーション | ||
4.MFCのDocument/Viewアーキテクチャの.NET化 | ||
5.MFCで書かれたDocumentを.NET化する2つの方法 | ||
Vista時代のVisual C++の流儀(後編) | ||
STL/CLRによるDocument/Viewアーキテクチャ | ||
1.STL/CLRとは | ||
2.STL/CLRの特徴 | ||
3.Visual Studio 2005で試す | ||
4.おまけ:NUnitの活用 | ||
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|