OverTakerさんの紹介していたC++/CLIの本は、書店で見かけました(こたつつきみかん » これからの開発者に送るお勧めの1冊)。そのときは「お~、C++/CLIが本になった」とパラパラめくっただけなので、内容までは詳しい印象が残っていません。目新しいことは見かけませんでしたが、それは基本的なことを充実させたことの裏返しだと思います。

先週予告したとおり、C++/CLIの話です。ここでは「型」を中心に話を進めたいと思います。

C++/CLIは所詮C++です。CLI (.NET Framework CLR)では値型・参照型の区別がありますが、C++/CLIでは後者をポインタのようなものとして表現しています。

1
System::Object^ obj = gcnew System::Object;</code>

CLIのガベージコレクションされるヒープにオブジェクトを作るときには、newではなくgcnewを使います。^(ハット記号)はポインタの*に相当するものだと思えばよいです。*を付けた型は「ポインタ型」と呼びますが、^を付けた型は「ハンドル型」と呼びます。ポインタと同じようにハンドルを通じてのメンバアクセスには->を使うなどします。

1
obj->ToString(), (*obj).ToString()

一方、値型はそのままです。普通のポインタでない形で扱います。

1
2
int x = 42;
System::Drawing::Point pt(4, 2);

ハンドルをハンドルと呼ぶ理由はポインタと違い、ポインタ演算ができないゆえでしょう。その代わりハンドル型に対しては演算子多重定義ができます。String::operator ==() – MSDNライブラリ

1
public: static bool operator ==(String^ a, String^ b)

このようなアクセス制御子publicの使い方(1つ1つの宣言のたびにアクセス制御子を書く)は普通のC++では珍しいですが、C#などの他言語と合わせるためCLIの世界ではよく見かけます。それはともかく、ついでにC#版を見ると次のようになっています。

1
public static bool operator ==(string a, string b)

C#では参照型に分類される型の引数は何も書かなくても参照渡しに相当することになります。これはABも同じです。

逆に値型の引数を見てみます。String::Substring

1
2
public: String^ Substring(int startIndex)
public string Substring(int startIndex)

値型であるint型の引数では、C++/CLIでもハンドルではなくint型そのものを渡すようになっています。

CLIで値型・参照型という違いもC++/CLIではハンドル(ポインタ風)かどうかという違いに集約されています。C++は値型・参照型の区別がなく、intなどの組込型もクラスなどの利用者定義型も、ローカル変数にしたりnewでヒープに割り当てたりが自由に選べます。まだ説明していませんが、値型へのハンドル型というものも作れますし、参照型をgcnewせず自動変数として使う記法もあります。特に後者はC++の重要な特徴をCLIで再現するために重要なものです。


といったところで続きは次回です。一週間経つより前に書くつもりです。読み返してみると、分かっている人にしか分からないですね。

スポンサード リンク

この記事のカテゴリ

  • ⇒ C++/CLI (1) 参照型とハンドル