我认为由于其传递引用功能,我可以在C ++中看到不同的行为,但我的代码似乎同意上述声明......
void reassign(string & a);
int main()
{
string x = "abcd";
cout <<"x is " << x <<" at " << &x <<endl; //"x is abcd at 0x7bc7ebd5b720"
reassign(x);
cout <<"x is " << x <<" at " << &x <<endl; //"x is efgh at 0x7bc7ebd5b720"
}
void reassign(string & a)
{
a = string("efgh");
}
因为&#34; string()&#34;构造一个新的字符串,为什么不重新分配&#34;功能改变原始字符串的地址?
答案 0 :(得分:6)
一旦分配了一个对象,就没有什么可以改变它的地址。您可以更改其内容(这是您的程序所做的),但地址将在对象的生命周期内保持不变。
如果使用new
动态创建对象,则可以将不同的对象分配给同一指针。但是,规则将保持不变:旧对象的地址不会更改,但您可以将新对象分配给旧指针。
void reassign(string* & a);
int main() {
string *x = new string("abcd");
cout <<"x is " << *x <<" at " << x <<endl; //"x is abcd at 0x95b7008"
reassign(x);
cout <<"x is " << *x <<" at " << x <<endl; //"x is efgh at 0x95b7030"
delete x;
return 0;
}
void reassign(string* & a) {
string *old = a;
a = new string("efgh");
delete old;
}
答案 1 :(得分:0)
你很困惑因为你的比喻不对。在Java中,没有“参数对象”这样的东西,因为“对象”本身不是Java中的值(Java中没有“对象类型”)。 Java中唯一的类型是基本类型和引用类型,其中“引用”是指向对象的指针。因此在Java中,您只能将对象指针作为变量或参数的值,并且只能通过指向对象的指针来处理对象。
“你无法改变指针指向的位置”是按值传递的结果。 Java始终是按值传递,这意味着对参数的赋值不能更改传递的变量的值。请记住,变量只能是基本类型或引用类型。在这里,您谈论的是参考类型。因此,引用类型变量的“值”是引用(指向对象的指针),即它指向的对象的地址。因此,您无法更改值意味着您无法更改指针指向的位置。
例如,在Java中,您可能会遇到以下情况:
public static void reassign(String a) {
a = new String("efgh");
}
public static void main(String[] args) {
String x = "abcd";
System.out.printf("x is %s at %x\n", x, System.identityHashCode(x)); // x is abcd at 25154f
reassign(x);
System.out.printf("x is %s at %x\n", x, System.identityHashCode(x)); // x is abcd at 25154f
}
此处,x
中的main
是指向对象的指针。 a
中的reassign
也是指向对象的指针。分配给a
中的指针参数reassign
对传递的指针变量x
没有影响(即它不会影响指针指向的位置),因为它是传值的。 / p>
C ++中上述代码的等价物如下:
void reassign(string *a) {
a = new string("efgh");
}
int main() {
string *x = new string("abcd");
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x82b1008
reassign(x);
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x82b1008
return 0;
}
除了上面显示的pass-by-value之外,C ++还具有pass-by-reference,其中对参数的赋值与分配给调用范围中的传递变量具有相同的效果。这与上面完全相同,但是通过引用传递:
void reassign(string *&a) {
a = new string("efgh");
}
int main() {
string *x = new string("abcd");
cout << "x is " << *x <<" at " << x << endl; // x is abcd at 0x8673008
reassign(x);
cout << "x is " << *x <<" at " << x << endl; // x is efgh at 0x8673030
return 0;
}
请注意,在这里没有任何情况下我们更改指向的对象。我们只是创建了一个新对象,并尝试将指针更改为指向此对象。旧对象仍然没有改变。改变对象的能力是一个独立的,正交的问题,从传值和传递引用,所以我们不在这里讨论它。