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 可能已经为我完成了取消引用,但我预计静态转换不会长。这也与自动拆箱有关吗?

4

4 回答 4

5

C++/CLI 允许这种语法有点令人遗憾。int 类型是值类型,帽子用于引用类型。您的“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 的“可变参数”性质所愚弄。

于 2009-01-22T02:15:35.460 回答
2

不要依赖 WriteLine 告诉您 *y 和 y 是什么,从调试器中运行它并自己检查 *y 和 y 以查看差异。

于 2009-01-22T02:18:19.870 回答
0

将值类型的句柄视为您可能自己编写的智能句柄,它具有用于转换的运算符重载。这样,使用可以提供 int 的句柄(通过转换运算符)以及取消引用句柄以获取对象中包含的 int 都可以。

关于 Writeline,我认为它就像隐式调用许多转换的流输出运算符。正如您可以安全地使用 cout << y,您可以编写 System::Console::WriteLine(y)。

于 2009-01-26T04:10:13.813 回答