Java的ArrayList和C++的vector很類似,都是很基本的線性數據結構。但是他們的表現卻不同。
在工作中碰到一個問題就是,搞不清楚到底傳進去的是一個新對象,還是當前對象的引用!
經過實戰分析:
在Java的ArrayList.add(e)中,傳入的是引用,因此當你傳入e以后,再改變e的成員,則ArrayList里的e也同樣會改變,因為本身e和ArrayList中的e就是同一個東西。
而C++的vector.push_back(e)則會調用拷貝構造函數,因此當你傳入e以后,再改變e的成員,則vector里的e不會變,因為已經是兩個對象了。
Java代碼:
import java.util.ArrayList; public class TestJavaArrayListAdd { public static void main(String[] args) { ArrayList<A> all = new ArrayList<A>(); //這里構造一個值為1的a,插入all並打印 A a = new A(1); all.add(a); TestJavaArrayListAdd tester = new TestJavaArrayListAdd(); tester.print(all); //改a的值為2,並再次打印all a.memberA = 2; tester.print(all); } private void print(ArrayList<A> all) { for (int i = 0; i < all.size(); i++) { System.out.print(all.get(i).memberA + " "); } System.out.println(); } } class A { public int memberA; A (int anotherMemberA) { this.memberA = anotherMemberA; } }
運行如下:
1
2
可以看到,對於外面引用的改變對於ArrayList里面的元素也起作用了,下面來看看C++會怎么樣。
C++代碼:
#include <iostream> #include <vector> using namespace std; class A{ public: A(int aa) { a = aa; cout<<"In Constructor(aa)"<<endl; } A(const A & another) { cout<<"In Constructor(&A)"<<endl; a = another.a; } void out() { cout<<a<<" "; } int a; }; void print(vector<A> &vec) { for (int i = 0; i < vec.size(); i++) { vec[i].out(); } cout<<endl; } int main() { vector<A> aVec; aVec.clear(); //弄1個值為1的a1,插入vector並打印 A a1(1); aVec.push_back(a1); print(aVec); //改a1的值為2,再打印 a1.a = 2; print(aVec); //修改vector內部的元素的值,再打印 aVec[0].a = 3; print(aVec); return 0; }
打印結果發現:
In Constructor(aa) In Constructor(&A) 1 1 3
說明確實調用了拷貝構造函數,那么vector內部的對象aVec[0]和外部的對象a1自然是兩個獨立的對象了,自然對a1.a的任何修改對於aVec內的值沒有影響,只有對vector里的東西的修改才有影響。
經過上述折騰,算是都搞清楚了。以后有不懂得問題,一定要照着全搞明白去搞,不要怕麻煩。