2

私はこれを正しく尋ねていないことも知っています。私の質問をより良くするのを手伝ってください。

ハンドルについて理解するのに少し苦労しています。ある意味では、ハンドルのように見えます。しかし、ポインターとは異なり、ハンドル変数に値を直接割り当てることができるようで、ハンドル自体ではなく、基になるデータ値に影響を与えます。

テスト コードは、ハンドルを使用しても、ハンドルを「逆参照」してデータを取得しても、同じ値が得られることを明確に示しています。明らかに、これはアンマネージ ポインターでは機能しません。私は何を理解していませんか?

#include <iostream>

int main()
{

  int ^y;
  int ^a, ^b, ^c;
  long x;

   y= gcnew int(100);
   a=y;
   b=y;
   c=y;

   c= gcnew int(200);
   b= 300;

   System::Console::WriteLine(y); // returns 100 (instead of something pointer-like)
   System::Console::WriteLine(*y); // also returns 100

   System::Console::WriteLine(a); // 100
   System::Console::WriteLine(b); // 300
   System::Console::WriteLine(c); // 200 

   x = static_cast<long>(y);
   *y = 10;

   System::Console::WriteLine(x); // 10
   System::Console::WriteLine(y); // 10
   System::Console::WriteLine(*y); // 10

  }

追加する編集 - WirteLine が逆参照を行ったのではないかと思いましたが、静的キャストが long にならないことを期待していました。これは自動ボックス化解除にも関連していますか?

4

4 に答える 4

5

C++/CLI でこの構文が許可されているのは少し残念です。int 型は値型で、hat は参照型に使用されます。「y」変数はintを格納せず、System::Objectを格納します。コンパイラは、割り当て時にボックス化命令を自動的に生成します。Console::WriteLine() は、ボックス化された int であるオブジェクトの値を表示するのに問題はありません。

経験則: クラス オブジェクトの場合は帽子を使用し、単純な値の型の場合は省略します。値型と参照型の違いと Dispose() が重要な理由を本当に理解するまでは、参照型のスタック セマンティクスを避けてください (ハットを省略して、スコープの終了時にデストラクタを自動的に呼び出すようにします)。

于 2009-01-22T03:02:02.760 に答える
2

WriteLine 使用の副作用。

'y' だけが 'オブジェクト参照' のように扱われ、おそらく IFormattable について調べられ、ToString() が呼び出されます。'*y' は int を渡しています。

これをテストするには、別の関数呼び出し Foo(int ^) を作成し、何を渡すことができるかを確認してから、'Foo(int)' に変更します。

WriteLine の「varargs」の性質にだまされているだけだと思います。

于 2009-01-22T02:15:35.460 に答える
2

*y と y が何であるかを知るために WriteLine に依存しないでください。デバッガーから実行し、 *y と y を自分で調べて違いを確認してください。

于 2009-01-22T02:18:19.870 に答える
0

値型へのハンドルは、自分で作成したスマートハンドルのようなものであり、変換のために演算子がオーバーロードされていると考えてください。このように、intを指定できるハンドルを使用すると(変換演算子を介して)機能するだけでなく、ハンドルを逆参照してintをオブジェクトに含めることができます。

Writelineに関しては、多くの変換が暗黙的に呼び出されるストリーム出力演算子のようなものだと思います。安全にcout<<yに移動できるのと同じように、System :: Console :: WriteLine(y)と書くことができます。

于 2009-01-26T04:10:13.813 に答える