歴史 Microsoft はMicrosoft Visual C++ 2002 (MSVC++)で Managed Extensions for C++ を導入しました。Microsoft は標準 C++ と Managed Extensions for C++ の間の差異を最小限に抑えようと試みた結果、両者の根本的な違いは構文的に不明瞭になりました。MSVC++ 2003 と 2005 では、Managed C++ でプログラムを作成するサポートも提供されました。2004 年に Managed Extensions for C++ は、 C++ を使用して共通言語インフラストラクチャ のプログラミングをサポートしようとする Microsoft の 2 回目の試みであるC++/CLI に置き換えられ、非推奨となりました。[ 2 ]
デザイン マネージドと は、.NET仮想マシン上で実行される、または.NET仮想マシンによって 管理される マネージドコード を指します。この仮想マシンは、バッファオーバーランチェックなどのランタイムチェックを強化することでセキュリティを向上させるサンドボックス として機能します。さらに、マネージドC++で記述されたアプリケーションは、標準C++アプリケーションのように直接ネイティブCPU 命令にコンパイルされるのではなく、CIL (共通中間言語)にコンパイルされます。
マネージド C++ コードは、C# やVisual Basic .NET など、CLR をターゲットとする他の言語と相互運用できるだけでなく、ガベージ コレクション などのCLR が提供する機能も利用できます。つまり、マネージド C++ は .NET 言語の中で独自の地位を占めています。ネイティブ C++ だけでなく、.NET 言語 (C#、VB.NET など) と直接通信できる唯一の言語です。他の .NET 言語は、PInvoke またはCOM を介してのみ C++ コードと通信できます。しかし、マネージド C++ はマネージド C++ と標準 C++ の両方のコンテキストで直接通信できるため、「橋渡し」としてよく使用されます。
機能性 マネージドC++で記述されたプログラムは、.NET FrameworkとCLR の追加機能を提供します。中でも特筆すべきはガベージコレクション で、プログラマーは手動でメモリ管理を行う必要がなくなります。ガベージコレクタ(GC)はCLRによって処理されます。メモリ管理は非常に高速に実行されますが、パフォーマンスが重視されるアプリケーションでは、ネイティブのアンマネージドコードの方が望ましい場合が多いでしょう。
マネージドC++は、オブジェクト指向プログラミング向けに設計されています。標準C++とマネージドC++の大きな違いは、多重継承 がサポートされていないこと、そしてCLRのガベージコレクタによって管理されるクラスは複数のクラスを継承できないことです。これはCLRの制限によるものです。
主な特徴:
拡張可能なメタデータ:管理対象コンポーネントの構造と型を記述するために提供される情報。ソフトウェアコンポーネントを作成するために拡張および再利用できます。C# および Visual Basic .NET で広く使用されています。 ガベージコレクション: CLR は、メモリ管理を自動化するガベージコレクタによって完全に管理されます。つまり、マネージド C++ コードでは delete 演算子を呼び出す必要はありません。 .NET 言語との相互運用性: .NET Framework を対象としたコードは、Microsoft Intermediate Language (MSIL、Java バイトコードに類似) の出力を生成するため、コンパイルされたモジュールやコンポーネント (アセンブリ) は、JScript .NET、C#、Visual Basic .NET、その他のサードパーティ製 .NET 言語など、.NET Framework を対象とした別の言語で記述された他のプログラム コンポーネントで再利用できます。 バージョン管理:既存のクライアント側ソフトウェアとのバイナリ互換性を損なうことなく、新しいメソッドやデータメンバーを既存の管理対象クラスに導入できます。 バイナリヘッダー:コンパイル済みのメタデータの再利用を可能にします。MSILにコンパイルされた任意の.exe、.dll、.obj、または.netmoduleをC++ソースファイルから参照できます。 バッファオーバーフロー保護 - C++にガベージコレクションが導入されたことで、マネージドC++は、標準C++におけるデータ型チェックの欠如によって引き起こされる一般的なバッファオーバーフロー エラーが発生しにくくなりました。ガベージコレクタは、これらのエラーの発生頻度を(完全にではないものの)低減するのに役立ちます。 .NET Frameworkベース クラス ライブラリ - マネージド C++ は、すべてのマネージド関数呼び出しと継承クラスが .NET Framework ベース クラス ライブラリ (BCL、FCL または Framework Class Library と呼ばれることもあります) から派生しているため、標準のアンマネージド コードよりも冗長性が低くなる可能性があります。このライブラリの API は、TCP/IP ネットワーク機能、テキスト操作機能、データ アクセス (ODBC から SQL まで)、XML サービス (XSD から XSL まで)、GUI プログラミング (Windows フォーム)、メール サービス (SMTP)、暗号化 (X509 証明書と XML デジタル署名)、MSIL 生成 (基本的に MSIL で命令を出力)、ファイル I/O、CLR ガベージ コレクタの手動操作、および WMI コンソールを操作するための管理情報を提供します。
ネイティブコードに対する利点 マネージドコードとアンマネージドコードは、同じCLIアセンブリ 内でシームレスに混在させることができます。これにより、プログラマは、.NET Framework に移植できないアンマネージドコードを完全に書き直すことなく保持することができます。ただし、このハイブリッドな手法を使用することには、いくつかの影響があります。 マネージドC++は、アンマネージドコードを含み、他のすべての.NET言語とネイティブに通信できる唯一の言語です。そのため、マネージドC++は、.NET環境のプログラマーと標準C++のプログラマーを含む、異なる言語を使用するプログラマー間の相互運用性を実現する上で非常に便利です。
管理されていないコードと比較した場合のデメリット マネージドC++は、多くの新しいキーワードや構文規則を導入しており、特にC++コードが直接インクルードされ、同じアセンブリ内でマネージドC++コードと直接やり取りする場合、コードの可読性を損なう可能性があります。 マネージドC++はC++/CLIに取って代わられ、 C++/CLI が標準化されたため、廃止されました。
完全マネージドコードと比較した場合のデメリット マネージドC++は、同じ結果が得られるプロジェクトに適用できる他の.NET言語よりも、開発時間が若干長くなります。マネージドC++には値型(__value構造体と__valueクラス)と参照型(__gc構造体と__gcクラス)の両方があるため、ポインタの使用は必須となる場合とそうでない場合があります。 マネージドC++はASP.NET Webアプリケーションを完全にサポートしていますが、開発は他の.NET言語や一部のサードパーティ製言語よりも困難です。 マネージドC++は、テンプレート(ネイティブC++との相互運用性のため)のみをサポートし、ジェネリクス(他のすべての.NET言語との相互運用性のため)はサポートしていません。C ++/CLIは、 テンプレート(コンパイル時)とジェネリクス(実行時)の両方をサポートしています。
例 以下の例は、マネージドC++と標準C++の使用例を比較したものです。
(グローバルな変更)CLRに移植される既存のC++コードには、以下の内容を追加する必要があります。 // Gello.cpp // 新しい using ディレクティブ #using <mscorlib.dll> // 別の using namespace ディレクティブ。 using namespace System ; int main () { Console :: WriteLine ( "Hello, world!" ); return 0 ; } 新しいプリプロセッサディレクティブ
が必要です。さらに、ベースクラスライブラリでより多くの名前空間を使用するために、より多くのライブラリをインポートするには、より多くの #using ディレクティブが必要です。
#using <System.Windows.Forms.dll> そして
using namespace System :: Windows :: Forms ; Windowsフォームを使用する。
CLRをターゲットとするコードをコンパイルするには、新しいコンパイラオプションを導入する必要があります。 cl.exe hello.cpp /clr /clr を使用すると、.NET Framework を参照するすべてのコードをCIL としてコンパイルできます。
クラスは、__gc拡張キーワードを使用してガベージコレクションの対象として指定できます。 // GarbageCollected.cpp #<mscorlib.dll>を使用 __gc クラス GarbageCollected { int * i ; char * g ; float * j ; }; int main () { while ( true ) { GarbageCollected ^ _gc = gcnew GarbageCollected (); } return 0 ; } 上記のコードは、メモリリーク の心配なくコンパイルおよび実行できます。クラスはgcガベージコレクタによって管理されているため、delete演算子を呼び出す必要はありません。管理されていないコードで同じことを実現するには、deleteキーワードが必要です。
// NotGarbageCollected.cpp class NotGarbageCollected { int * i ; char * g ; float * j ; }; int main () { while ( true ) { NotGarbageCollected * g = new NotGarbageCollected (); delete g ; } return 0 ; } 注:
__gc で指定されたクラスには、コンストラクタを宣言できます。 __gc で指定されたクラスには、デストラクタを宣言できます。 __gc で指定されたクラスは、複数のクラスを継承することはできません。(これは CLR の制限事項です) __gc で指定されたクラスは、__gc で指定されていない別のクラスを継承することはできません。 __gc で指定されたクラスは、__gc で指定されていない別のクラスに継承することはできません。 __gc 指定クラスは、任意の数の __gc インターフェースを実装できます。 __gc 指定クラスは、アンマネージド インターフェイスを実装できません。 __gc 指定クラスは、デフォルトではそのアセンブリ外からは見えません。 public __gc class MyClass { // ... }; __gc 指定クラスのアクセスを変更するための public キーワード。
__gc 指定クラスは、delete キーワードを使用して手動で破棄できますが、それは __gc 指定クラスにユーザー定義のデストラクタがある場合に限ります。
インターフェースは、__gc拡張キーワードを前に付けて宣言できます。例: // MyInterface.cpp #using <mscorlib.dll> __gc __interface MyInterface { void init (); int common (); } 上記のコードは、シンプルなDLLファイルを生成するために、/clrおよび/LDオプションを指定してコンパイルする必要があります。
注:
__gc __interface には、データ メンバー、静的メンバー、ネストされたクラス宣言、およびアクセス指定子を含めることはできません。 __gc __interface は、別の __gc __interface インターフェースまたは System::Object からのみ継承できます。System::Object からの継承がデフォルトの動作です。 __gc __interface には、宣言された関数プロトタイプの実装 (本体コード) を含めることはできません。
他の言語との比較 以下に、マネージドC++と、概念的に類似した他のよく知られたプログラミング言語との主な相違点とプログラミング標準を示します。
標準C++デメリット
ネイティブの C++コードの方が実行時速度が速い場合がある。C++では、対象システムにコンパイラやマネージドランタイム環境をインストールする必要はありません。 C++はジェネリックプログラミング をサポートしています。ただし、C++/CLIの最終リリースまでは、マネージドC++プログラマーはジェネリックを使用するための回避策を講じる必要があります。 C++はキーワード「const」とconstの正当性 をサポートしています。JavaやC#のようなマネージドC++にはこの機能はありません。代替策としては、マネージドクラスを不変に するか、パブリックインターフェース上のセットアクセサを制限する方法があります。 C++ コードは CLR の制約を受けません。例えば、CLR はクラスが他のクラスをプライベートまたは protected に継承することを許可しないため、次のコードはコンパイラ エラーになります。 public __gc class First { int i ; }; public __gc class Second : private First { int h ; i = h ; }; // エラー public __gc class Third : protected First { int h ; i = h ; }; // エラー マネージドC++の__gcクラスは複数のクラスから継承することはできないため、以下の記述はコンパイラエラーになります。 __gc class First {}; __gc class Second {}; __gc class Third : public First , public Second {}; // エラーが発生します 利点
マネージドC++は、通常のC++よりも高度なリフレクションをサポートしており、 コードの機能や目的によっては、一般的に非常に便利です。 マネージドC++は、他のサードパーティ製言語を含む、.NET対応のすべての言語と相互運用できます。 マネージドC++では、ガベージコレクションが行われます。標準C++では、メモリ管理とメモリ割り当てはプログラマの責任です。
Java 相違点
Javaコードを実行するには適切な仮想マシンが必要であり、マネージドC++コードを実行するには適切な.NET Frameworkの実装が必要です。 デメリット
Javaはソースコードに関するドキュメントを提供するが、マネージドC++は提供しない。 JavaにはJavaプログラマーが利用できる開発ツールが多数ありますが、マネージドC++はVisual Studio .NET でのみ利用可能です。 利点
C#相違点
C#はC++と同様にポインタをサポートしていますが、この機能はデフォルトでは無効になっています。 デメリット
Java と同様に、C#もマネージドコードを扱う際には構文がシンプルです。C#は、構文や構造上の慣習が非常に似ているため、マネージドC++と基本的に同じ結果を達成できます。 マネージドC++は、CLRに導入されたことで厳密に型付けされた言語ではあるものの、同じコードベースにアンマネージドのコンパイル済みコードが混入するとエラーが発生しやすい。一方、C#は純粋なMSILである。 利点
C# は、コンピュータシステムに低レベルでアクセスするために、.NET Framework およびそれが提供するクラスライブラリを使用する必要があります。 C言語やC++言語で書かれたアプリケーションを.NET Frameworkに移植する場合、マネージドC++を使用するとはるかに簡単になります。 Microsoft Visual C++ .NETコンパイラは、マネージドC++をコンパイルして.NET Frameworkをターゲットとするため、生成されるアセンブリコードにおいて、より成熟した命令セットを生成することになり、パフォーマンスが向上します。
参考文献 ↑ 「翻訳ガイド: C++ のマネージド拡張機能から C++/CLI へのプログラムの移行」。マイクロソフト 。2004 年 8 月。2009年 11 月 11 日 に取得 。 ↑ Sutter, Herb. "C/C++ の設計理念" (PDF) . p. 6. 2017-08-30 のオリジナルから アーカイブ (PDF) . 2018-06-12 に取得 .
外部リンク C++ 用マネージド拡張機能 (MSDN) 記事:C++ / CLI – Microsoft Visual C++ 再頒布可能パッケージがインストールされていない場合、マネージド C++ DLL を使用する方法