我在VS 2010中使用C ++ / CLI。感谢this回答我已经了解到在C ++ / CLI中你通过引用传递了一个对象,如此
voin func(String ^ %string){
//modify string
}
我想要做的是将一些参数传递给GetInput
形式的构造函数。然后从用户输入到此表单修改它们。表单关闭后,调用者表单将获得以GetInput
形式输入的值。
它适用于我List<double>
,但没有String^
。这是代码:
public ref class GetInput : public System::Windows::Forms::Form
{
public:
List<double>^ _data;
String ^ _string_data;
GetInput(List<double>^ %data, String ^ %string_data){
_data = data;
_string_data = string_data;
//this code is here just for the sake of an example,
//it's actually in one of the methods
_data->Add(0.5);
_string_data = "15";
}
//void buttonClickHandler where i actually want to modify data and string_data
}
List _data
被修改,以及传递的data
,但是当我修改String _string_data
时,原始的string_data
保持不变。但是,如果我修改string_data
本身 - 它工作正常。此外,跟踪引用不能是类的成员,因此将_string_data声明为引用不起作用。
明显的解决方法是传递由List^
组成的String^
,但我想知道为什么它不起作用,以及是否有办法使我的方法有效。来自本机C ++,这似乎是一个非常简单的方法 - 只需将指针传递给数据。但是C ++ / ClI跟踪引用是不同的。
此外,我读到“当对象在垃圾收集堆上移动时,跟踪引用会更新。” (source)。有人可以澄清这意味着什么吗?我怀疑这包含了我的问题的答案,但我不太明白:)
更新 基本上我想在C ++ / CLI中执行此操作:
class GetInput {
string * s;
GetInput(string * caller_wants_this_modified){
s = caller_wants_this_modified;
}
void method_to_modify_the_string(){
(*s) = "New string value"; // modifies the string passed by the caller
}
}
我需要将传递给构造函数的指针保存为类成员,然后在其中一个成员函数中更改此指针指向的数据。
答案 0 :(得分:3)
但是C ++ / ClI跟踪引用是不同的
认为跟踪参考&#34;有一些神奇的东西。或许是什么让你在这里遇到麻烦。 C ++ / CLI语言和文档非常重要,它是为本机C ++程序员编写的。它实际上 并没有那么不同。
这只是一个指针。
它的行为与指针完全相同,在物理上都在处理器和语法上。唯一&#34;特别&#34;关于它是垃圾收集器可以找回它。必要的,以便它能够完成它的工作。 C ++ / CLI设计者选择使用^
而不是*
,因为他们确实有限制。简单的,例如,你不能使它成为非托管类的成员。 GC无法知道它在内存中的位置,因此无法完成其工作。
你的问题非常简单,你有两个指针。 _string_data
和string_data
。请注意,您选择的名称并不能完全帮助您做到正确。您更新了_string_data指针,它现在指向&#34; 15&#34;。但不您通过引用传递的指针,它仍然指向原始字符串。当然,没有任何更改会传播回调用方。不知道意图是什么,而是任意:
_string_data = "15";
string_data = _string_data;
现在调用者也会看到其参考更新为&#34; 15&#34;。两个指针现在指向同一个对象。
请注意,List<>
参数也是错误的。你做了不更新data
指针。你也没需要,你没有创建一个新的List对象。您的代码只修改了对象,而不是指向对象的指针。所以通过引用传递它是完全没必要的。
还有一个细节与这个问题有关。请注意,您修改了List&lt;&gt;对象通过调用其Add()方法。但是你不能为String做同样的事情。它是 immutable ,它的方法和属性都不允许您修改其内容。这给了它非常理想的行为,字符串总是线程安全的,并且作为参数传递给方法总是安全的。确保永远不会被修改。它的行为就像一个价值。
或者换句话说,你有通过引用传递字符串指针,以将更改传播回调用者。
请注意List&lt;&gt;不是不可变的,你的Add()调用突然改变了对象。使用您的类的客户端程序员不太可能期望这种情况发生。 C ++中的 const 关键字是表达差异的一种很好的方式。然而,它在C ++ / CLI中并没有那么好用,其他.NET语言也不了解它。您可以在声明中使用 const ,但不能在运行时强制执行。