ArrayList vs Vector通过引用传递

时间:2016-01-24 04:01:57

标签: java c++

在Java中,如果您有以下代码,则list1和list2最终指向同一个对象,因此list2中的更改将导致list1发生更改。

ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(2);
list1.add(3);
ArrayList<Integer> list2 = new ArrayList<Integer>();
list2 = list1;
list2.set(0, 10);

for(int i =0; i<list1.size(); i++){
    System.out.println(list1.get(i));
}
for(int i =0; i<list2.size(); i++){
    System.out.println(list2.get(i));
}

输出最终是:

10
2
3

10
2
3

但是,在C ++中,行为是不同的?

vector<int> list1;
list1.push_back(1);
list1.push_back(2);
list1.push_back(3);
vector<int> list2;
list2 = list1;
list2.at(0) = 10;
for(int i =0; i<list1.size(); i++){
    cout << list1[i] << endl;
}

for(int i=0; i<list2.size(); i++){
    cout << list2[i] << endl;
}

输出最终为:

1
2
3

10
2
3

有人可以解释一下吗?

3 个答案:

答案 0 :(得分:3)

详细说明我的评论:

在Java中,=运算符on(赋值兼容)引用类型只是复制引用值。 (如果您来自C / C ++世界,请考虑指针。)要记住的关键是在Java中,任何变量都不是对象;它是对象的原始值或引用

在您的C ++示例中,=运算符正在处理实际对象,而不是引用。 (对于其他数据类型,故事可能会有所不同。)来自the docs for std::vector::operator=

  

将新内容分配给容器,替换其当前内容,并相应地修改其大小。

所以在C ++中,list2在赋值后仍然是一个单独的vector对象,只有list1的内容副本。在Java中,一旦您将ArrayList重新分配为与list2相同的对象的引用,您分配给list2的第二个list1对象就会变为垃圾。

答案 1 :(得分:1)

简单解释一下:

Java使用引用语义。在这种情况下,对于list2 = list1之后的同一对象,您有两个名称(list1,list2)。

C ++使用值语义。 list1的被复制到list2,你有一个新的无关对象(list2),可以在不影响复制对象(list1)的情况下进行变异。

答案 2 :(得分:1)

在C ++中使用相同行为的最简单方法是将list2声明为引用 - 但是,这要求赋值发生在list2的声明中,而不是在以下之后:

vector<int> &list2 = list1;