zoukankan      html  css  js  c++  java
  • 论Java的ArrayList.add(e)和C++的vector.push_back(e)的区别

    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里的东西的修改才有影响。

    经过上述折腾,算是都搞清楚了。以后有不懂得问题,一定要照着全搞明白去搞,不要怕麻烦。

  • 相关阅读:
    如何为你的Airtest报告自定义名称
    Go打包构建 生成32位64位应用程序 加入前端项目
    DNS解析与DNS缓存清理
    sharepoint2013安装记录
    C# winform自托管WebApi及身份信息加密、Basic验证、Http Message Handler、跨域配置
    IM扫码登录技术专题(四):你真的了解二维码吗?刨根问底、一文掌握!
    IM开发干货分享:万字长文,详解IM“消息“列表卡顿优化实践
    阿里IM技术分享(五):闲鱼亿级IM消息系统的及时性优化实践
    使用oracle序列+oracle定时任务获取每月从1开始的流水码
    为什么我的数据库查询越来越慢
  • 原文地址:https://www.cnblogs.com/lihaozy/p/3182618.html
Copyright © 2011-2022 走看看