Garbage Collection

塵も積もれば山

目次

Blog 利用状況

ニュース

コミケで受けていた通販をすべて発送しました。詳しくはこちらの記事にて
C++とかC#とか数学ネタを投下していく予定です。
それ以外の日々の四方山話を綴った日記はこちら

書庫

日記カテゴリ

[C++/CLI]Stringの糸口

意外に、C++/CLIで検索する方がいるようなので、
C++/CLIを始めたときに混乱していたネタを投下します。

C++/CLIを始めてから、よくわからない印象を持ったのが文字列の扱いです。
ハンドル型なのに実体のような動きをする存在で、不思議に見えました

System::String ^str1 = gcnew System::String("abc");
System::String ^tmpstr = str1;

Console::WriteLine(str1);
Console::WriteLine(tmpstr);

str1 = gcnew System::String(str1 + "def");

Console::WriteLine(str1);
Console::WriteLine(tmpstr);

初期化はchar*と同じようにできますが、なぜか足し算もできます。
演算子オーバーロードでうまくやっているんでしょうと理解していました。

そして、いちばん混乱したのがこれ。

System::String ^str1 ="abc";
System::String ^tmpstr = str1;

Console::WriteLine(str1);
Console::WriteLine(tmpstr);

str1 += "def";

Console::WriteLine(str1);
Console::WriteLine(tmpstr);

もし、char *のように振舞うのであれば、
2回目のWriteLineでは両方とも"abcdef"が出力されないといけませんが、
実際には、str1は"abcdef"、tmpstrは"abc"と出力されます。

しかし、ハンドル型なので実体を持ち運んでいるわけではないはず。
Stringだけ特殊な扱いを受けている??

どうにも解せないときに出会ったキーワードが以下の2つ。
・ボックス化
・String不変

キーワードにしたがって、上のソースを書きなおしてみます。

System::String ^str1 = gcnew System::String("abc");
System::String ^tmpstr = str1;

Console::WriteLine(str1);
Console::WriteLine(tmpstr);

str1 = gcnew System::String(str1 + "def");

Console::WriteLine(str1);
Console::WriteLine(tmpstr);

まず最初の変数初期化ですが、ボックス化によりgcnewが付与されます。
ですから、char*のように先頭ポインタだけを指しているわけではありません。

そして、+=演算子。
これがもう一つのString不変です。
Stringの内容が変化を受ける場合、そのつど新しい領域が確保されます。
ですから、後半のstr1とtmpstrでは指しているアドレスが違うわけでです。

String不変の観点でSystem::Stringを調べてみると、
ハンドル型の変数を書き換えられない状況では、ReadOnlyになっています。
(たとえば、[]演算子)

StringはUnicodeを格納するクラスなので、char*やstd::stringとは違い、
固定文字列を持ち運ぶもの、と理解しておくといいでしょう。

投稿日時 : 2008年11月28日 6:11

Feedback

# re: [C++/CLI]Stringの糸口 2008/11/28 8:11 T.Hirase

自分は、昔Javaでハマりました。
Javaのjava.lang.Stringも同じなんですよね。

不変な文字列は、.NETならSystem.String、Javaならjava.lang.String。
可変な文字列は、.NETならSystem.Text.StringBuilder、Javaならjava.lang.StringBuffer。

最近の流れなのかと。

# re: [C++/CLI]Stringの糸口 2008/11/28 11:18 ごう

初コメントです。
私も(VS2003の頃の)Managed C++でこれにハマっていました。
従来の資産のコードを使いたいのに、フォーム上のTextBoxから取得できるのはSystem::String*… 
どうやってchar* に変換すればいいかわからなくて調べまくったのを思い出しました(^_^;

# re: [C++/CLI]Stringの糸口 2008/11/28 16:17 επιστημη

自分自身を書き換えることができないのに
operator += を定義するのはマチガイじゃないかと思ふ...

# string-でつながるブログリング 2008/12/08 7:53 blogring.org

stringに関するブログをまとめています。

タイトル  
名前  
Url
コメント