C /CLIとは? わかりやすく解説

クロロヨードカルベン

分子式CClI
その他の名称Chloroiodocarbene
体系名:クロロヨードカルベン


C++/CLI

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/09/14 21:57 UTC 版)

C++/CLIは、.NET Framework共通言語基盤 (CLI) に対応し、共通言語ランタイム (CLR) 上で実行されるプログラムを記述するために、マイクロソフトC++を拡張したプログラミング言語である。前身であるC++マネージ拡張に比べて単純でわかりやすい構文になり、可読性も向上している。Microsoft Visual Studio 2005からサポートが追加された。

C++/CLIはEcma Internationalで標準化されている[1]。C++/CLIに対応したコンパイラとしてMicrosoft Visual C++ 2005 (8.0) 以降がある。ほかにもClang上で実装する試みも存在する[2]

.NET Frameworkだけでなく.NETでも利用可能であり、.NET Core 3.1およびVisual Studio 2019 (16.4) からサポートが追加された[3]が、サポートされるプラットフォームはMicrosoft Windowsのみである[4]

構文の変化

C++マネージ拡張がC++のスーパーセット(上位互換)指向であった[注釈 1]のに対し、C++/CLIは独立した別の言語である[注釈 2]。これにより、特に曖昧な識別子の削除や、.NET固有の機能追加に関連する大きな構文上の変更が入っている。

もっとも大きな構文の違いとしてはnew演算子が挙げられる。C++/CLIでは.NETの参照型インスタンスを作るための演算子をgcnewに分離した。また、.NETのジェネリクスに対応する構文も追加された。

C++/CLIも標準C++とは概ね互換性があるが、C++11で追加された<atomic>など、一部の標準ライブラリを使ったコードをコンパイルすることができないなどの問題があった。Visual Studio 2022 (17.6) ではC++/CLIモードがC++20モードとの併用に対応し、また標準C++との互換性問題が緩和されている[6]

新しい構文機能やキーワードは、C#の影響を受けているものも多い。なお、C++/CLIの独自拡張機能のうち、overrideenum classのように、のちに標準C++に取り込まれたものもいくつかある[7]。ただし、enum classはC++/CLIと標準C++とで互換性がなく、区別するためにC++/CLIコードの修正が必要になるケースもある[8]

Microsoft Windows 8で導入されたWindowsランタイムを利用するコードをC++で効率的に記述できるようにするために、Visual Studio 2012では新たな独自拡張言語としてC++/CX英語版[9]のサポートが追加されたが、このC++/CXもC++/CLIとよく似た構文を採用している。ただしC++/CLIはマネージ言語拡張であるのに対し、C++/CXはネイティブ言語拡張である。

ハンドル

マネージ拡張C++には、2種類のポインタが存在した。従来からのC++ポインタである__nogcポインタと.NETの参照型オブジェクトを指す__gcポインタである。一方C++/CLIでは、ポインタはC++のポインタしかなく、.NETの参照型のオブジェクトを指すものは「ハンドル」と呼称することになった。ハンドル型はクラス名*に代わってクラス名^という構文を使う。これにより、.NETでガベージコレクションされるオブジェクトとそうでないものとが明確になり、マネージドとアンマネージドが混合しているコードが分かりやすくなった。gcnew は、C#でのnewに相当する。またハンドルからメソッドやプロパティへのアクセスはアロー演算子 (->) を用いる。

// マネージ拡張C++
#using <mscorlib.dll>
using namespace System;
using namespace System::Collections;

__gc class ReferenceType
{
private:
    String* stringVar;
    int intArr __gc[];
    ArrayList* doubleList;
public:
    ReferenceType(String* str, int* pointer, int number) // どれがマネージ型だろうか?
    {
        doubleList = new ArrayList();
        intArr = new int __gc[8];
        Console::WriteLine(String::Concat(str->Trim(), number.ToString()));
    }
};
// C++/CLI
#using <mscorlib.dll>
using namespace System;
using namespace System::Collections::Generic;

ref class ReferenceType
{
private:
    String^ stringVar;
    array<int> intArr;
    List<double>^ doubleList; // ジェネリック型の構文が追加された
public:
    ReferenceType(String^ str, int* pointer, int number) // 区別が容易
    {
        doubleList = gcnew List<double>();
        intArr = gcnew array<int>(8);
        Console::WriteLine(str->Trim() + number); // Stringの連結に+演算子が使用可能となった
    }
};

追跡参照

C++/CLIの追跡参照トラッキング参照)は値ではなく参照で渡されるハンドルである。これらはC#のrefVisual Basic .NETByRefに相当する。C++/CLIはハンドルへの追跡参照を示すのに^%という構文を使用する。これは標準C++で「ポインタへの参照」を表す構文*&に似ている。

下記のコードは追跡参照の使用例である。仮に、下のコードでString^% sString^ sに変えてしまうと、参照ではなく値を渡すことになるため、sは配列にセットされた文字列ハンドルをコピーするだけとなる。そのため、arrの各要素は初期化されないままになってしまう。

{
    array<String^>^ arr = gcnew array<String^>(10);
    int i = 0;

    for each (String^% s in arr)
        s = i++.ToString();
}

加えて上記のコードは.NET言語の間でも表現力に差があるという例になる。C#のforeach文ではforeach (ref string s in arr)というようにコレクション要素を参照として取得することができないため、例えば以下のような回避策を使うしかない。

{
    string[] arr = new string[10];

    for (int i = 0; i < arr.Length; ++i)
        arr[i] = i.ToString();
}

C++/CLIには、C#のoutパラメータ修飾子に直接相当する構文は存在しない。C#を含む他の.NET言語と相互運用する際に必要な場合、属性構文[System::Runtime::InteropServices::Out]を使い、メソッド引数を方向属性System::Runtime::InteropServices::OutAttributeで修飾する。

ファイナライザと自動変数

そのほかの変化として、C++/CLIではガベージコレクション時に実行されるファイナライザの構文が!クラス名()となったことが挙げられる。そして~クラス名()は従来のC++と同じ意味のデストラクタとなった。さらに、下の例にあるような新しい構文では、従来のC++と同じくデストラクタは自動的に呼ばれる。共通中間言語 (CIL) 上では、C++/CLIのデストラクタはIDisposableインターフェイスのDisposeメソッドとして実装される。C++/CLIコンパイラがそのようにコンパイルする。このためC++/CLIでも引き続きRAIIが可能である。

// C++/CLI
// デストラクタを定義すると、IDisposableを明示的に指定しなくても、コンパイラが自動的にIDisposableを実装すると判断する。
ref class MyClass // : IDisposable
{
public:
    MyClass() {} // コンストラクタ。
    ~MyClass() {} // デストラクタ。コンパイラによってIDisposable::Dispose()に変換される。

    static void Test()
    {
        {
            MyClass x; // ハンドルでなく初期化子も無い:コンパイラがコンストラクタを呼ぶ。
            x.ToString();
            // コンパイラはブロック全体を包むfinallyを作り、その中で自動変数xのデストラクタを呼ぶコードを自動生成する。
        }
        MyClass^ user;
        try
        {
            user = gcnew MyClass();
            user->ToString();
        }
        finally { delete user; }
    }
protected:
    !MyClass() {} // ファイナライザ。Object::Finalize()を直接オーバーライドすることはできない。マネージ拡張C++ではvirtual void Finalize()という構文だった。
};
// C#
class MyClass : IDisposable
{
    public MyClass() {} // コンストラクタ。
    ~MyClass() {} // ファイナライザ(旧称デストラクタ)。Object.Finalize()を直接オーバーライドすることはできない。
    public void Dispose() {} // IDisposable.Dispose() メソッドの実装。

    public static void Test()
    {
        using (MyClass x = new MyClass())
        {
            x.ToString();
        }
        // コンパイラはusingブロックを抜けるときにx.Dispose()を必ず呼ぶコードを自動生成する。
        // つまり以下のコードに等しい。
        MyClass user;
        try
        {
            user = new MyClass();
            user.ToString();
        }
        finally { if (user != null) user.Dispose(); }
    }
}

演算子の多重定義

アンマネージドのC++に関しては演算子の多重定義はおおむね正確に働く。すべての*^となり、すべての&%となるが、それ以外の構文はそのままでも多重定義を実装できる。また、それに加えてクラス自身に対してだけでなくそれらのクラスへのハンドルに対しても演算子多重定義が可能となった。従来のC++ではポインタ型同士に対して多重定義できなかった。また、CLIに適合するため演算子の多重定義をクラスの静的メンバとして実装することも可能になった。.NET Frameworkの参照クラスでもハンドルを引数に取る演算子の多重定義は静的メンバとして実装されている。

これは、中の文字列が同一ならば、2つの異なるStringの参照を==演算子で比較しても、String==演算子の多重定義によって結果がtrueとなることを意味する。もちろん、マネージコードを書くときだけに限らず、常にそうあるべきであるように、演算子の多重定義は多態的でない。従って、Object^へのキャストは多重定義のセマンティクスから逃れることになる。

//参照演算子の多重定義の効果
String ^s1 = "abc";
String ^s2 = "ab" + "c";
Object ^o1 = s1;
Object ^o2 = s2;
s1 == s2; // true
o1 == o2; // false

標準的なセマンティクスではネイティブ型や値型、仮に型Tに対しては、従来のC++のようにTやT const&を引数に取る演算子を定義し、参照クラス型Rに対してはハンドルR^を引数に取る演算子を定義することになる。ただ、C++だけのプロジェクトでは、ハンドル型を引数に取る演算子多重定義を使わないようにする、つまり参照クラスに対しても従来のC++の演算子の多重定義方式のように参照 (R const%) を引数に取るという手段も考えられる。そのような例は、演算子ではないがコピーコンストラクタや代入演算子の実装で使われることが考えられる。

脚注

注釈

  1. ^ 非標準のキーワードは__gc__valueのように、処理系のために予約された識別子[5]を使用することによって、標準C++のキーワードと衝突しないように配慮されていた。
  2. ^ 例えばabstractsealedgenericといった独自のキーワードが追加されている。

出典

関連項目

外部リンク


C++/CLI

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2019/02/02 08:52 UTC 版)

New演算子」の記事における「C++/CLI」の解説

C++/CLIでは、C++new演算子のほかに、マネージヒープから記憶域を確保するgcnew演算子存在するSystem::Object^ o = gcnew System::Object; gcnewには、配置構文存在しないまた、gcnewにはnew[]演算子相当する配列構文存在しないCLI配列マネージ配列)の作成には、arrayキーワード (cli::array型) を用いる。 array^ a1 = gcnew array(10); //要素101次元配列array^ a2 = gcnew array(3, 4); //3×4の2次元配列 ただし、gcnewには配列初期化構文存在するarray^ a1 = gcnew array(4) {0, 1, 2, 3};array^ a2 = gcnew array {0, 1, 2, 3}; //上と同じ。初期化子から要素数が算出されるarray^ a3 = gcnew array {{0, 1}, {2, 3}}; //多次元配列の例

※この「C++/CLI」の解説は、「New演算子」の解説の一部です。
「C++/CLI」を含む「New演算子」の記事については、「New演算子」の概要を参照ください。


C++/CLI

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2016/06/19 16:11 UTC 版)

Microsoft Visual C Sharp」の記事における「C++/CLI」の解説

C++.NET Frameworkに対応させた言語処理系としてVisual C++存在する

※この「C++/CLI」の解説は、「Microsoft Visual C Sharp」の解説の一部です。
「C++/CLI」を含む「Microsoft Visual C Sharp」の記事については、「Microsoft Visual C Sharp」の概要を参照ください。


C++/CLI

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/08/13 22:03 UTC 版)

Microsoft Visual C++」の記事における「C++/CLI」の解説

詳細は「C++/CLI」を参照 C++/CLIは(文法不明瞭な部分のあった)マネージ拡張C++代わるCLS満たすC++を基にしたプログラミング言語であり、Visual C++ 2005以降搭載されている。なおC++/CLI環境では、従来C++はアンマネージではなくネイティブ形容される。

※この「C++/CLI」の解説は、「Microsoft Visual C++」の解説の一部です。
「C++/CLI」を含む「Microsoft Visual C++」の記事については、「Microsoft Visual C++」の概要を参照ください。


C++/CLI

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/02/08 17:59 UTC 版)

sizeof」の記事における「C++/CLI」の解説

C++/CLIのsizeof演算子ネイティブ型(基本型およびポインタ型)に用い限りコンパイル時定数となり、基本的にC++と同じである。しかし値クラス (value class) 型、(マネージハンドル型やジェネリック型引数に対して用いられときにはコンパイル時定数でなくなる。また参照クラス (ref class) 型やインターフェイス型に対して用いることはできない(不正となる)。

※この「C++/CLI」の解説は、「sizeof」の解説の一部です。
「C++/CLI」を含む「sizeof」の記事については、「sizeof」の概要を参照ください。

ウィキペディア小見出し辞書の「C /CLI」の項目はプログラムで機械的に意味や本文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。 お問い合わせ



固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「C /CLI」の関連用語

C /CLIのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



C /CLIのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
独立行政法人科学技術振興機構独立行政法人科学技術振興機構
All Rights Reserved, Copyright © Japan Science and Technology Agency
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのC++/CLI (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
ウィキペディアウィキペディア
Text is available under GNU Free Documentation License (GFDL).
Weblio辞書に掲載されている「ウィキペディア小見出し辞書」の記事は、WikipediaのNew演算子 (改訂履歴)、Microsoft Visual C Sharp (改訂履歴)、Microsoft Visual C++ (改訂履歴)、sizeof (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。

©2024 GRAS Group, Inc.RSS