zoukankan      html  css  js  c++  java
  • 拷贝构造函数

    我们先看一个普通的构造函数的使用

    class Test
    {
    private:
        /* data */
    public:
        Test(int a);
        ~Test();
        int A;
    };
    
    Test::Test(int a)
    {
        A = a;
    }
    
    Test::~Test()
    {
    }
    
    
    int main()
    {
        Test test(1);
        cout<<test.A<<endl;
    
    }

    我们定义了一个类 Test 并用了类名定义了一个构造函数,用来传入成员变量A的值。

    这是一个正常的构造函数的用法。

    那么拷贝构造函数什么时候用呢?

    当我想用一个对象去初始化另一个对象的时候。

    Test A;
    Test A(B);

    就需要用到拷贝构造函数,我们看一下怎么写

    class Test
    {
    private:
        /* data */
    public:
        Test(int a);
        Test(const Test &q);
        ~Test();
        int A;
    };
    
    Test::Test(int a)
    {
        A = a;
    }
    
    Test::Test(const Test &q)
    {
        A = q.A + 1;
    }
    
    Test::~Test()
    {
    }
    
    
    int main()
    {
        Test test(1);
        Test test2(test);
        Test test3 = test;
        cout<<test.A<<endl;
        cout<<test2.A<<endl;
        cout<<test3.A<<endl;
    }

    输出结果

    1
    2
    2

    代码中标红的部分,就是拷贝构造函数,和他的调用方法。为了区分 用拷贝构造函数赋值的对象,所以我给 A 加了 1 .

    假设现在我有一个普通函数调用了刚创建的类,我们看一下运行结果

    class Test
    {
    private:
        /* data */
    public:
        Test(int a);
        Test(class Test &q);
        ~Test();
        int A;
    };
    
    Test::Test(int a)
    {
        A = a;
    }
    
    Test::Test(class Test &q)
    {
        A = q.A + 1;
    }
    
    Test::~Test()
    {
    }
    
    void get(Test p)
    {
        cout<<"the A int get() is : "<<p.A<<endl;
    }
    
    
    int main()
    {
        Test test(1);
        Test test2(test);
        Test test3 = test;
        cout<<test.A<<endl;
        cout<<test2.A<<endl;
        cout<<test3.A<<endl;
        get(test2);
    }

    运行结果:

    1
    2
    2
    the A int get() is : 3

    证明我们在调用 get函数,传参的时候  Test p 又重新调用了一次拷贝构造函数,所以输出的值是3

    如果我要在构造函数中调用构造函数,会是什么样的结果呢?
    看这样的一个例子

    class Test
    {
    private:
        /* data */
    public:
        Test(int a,int b);
        Test(int a,int b,int c);
        ~Test();
        int A,B,C;
    };
    
    Test::Test(int a,int b)
    {
        A = a;
        B = b;
        Test(a,b,100);
    }
    
    Test::Test(int a,int b,int c)
    {
        A = a;
        B = b;
        C = c;
    }
    
    Test::~Test()
    {
    /*  cout<<"---------"<<endl;
        cout<<A<<endl;
        cout<<B<<endl;
        cout<<C<<endl;
        cout<<"---------"<<endl;
    */
    }
    int main(void) { Test test(1,1); cout<<test.A<<endl; cout<<test.B<<endl; cout<<test.C<<endl; }

    重载了构造函数并且在2个参数的构造函数中调用了3个参数的构造函数。结果会是 a = 1 b = 1 c = 100吗

    输出结果如下:

    1
    1
    30

    第三个数字并非我们想要的100

    我们在析构函数中加上打印,看一下输出结果

    ---------
    1
    1
    100
    ---------
    
    1
    1
    30
    
    ---------
    1
    1
    30
    ---------

    中间红色部分是主函数中的打印结果 1 1 30

    前后两次是析构函数打印出来的,证明一开始c = 100 确实真的传入了对象当中,但是被析构函数释放掉了

    也就是说在执行2个参数的构造函数中,执行了一次析构函数。

    我们尽量避免不断的多次调用构造函数

  • 相关阅读:
    web前端学习笔记(CSS盒子的定位)
    web前端学习笔记(CSS盒子的浮动)
    数百篇「原创」文章,助你完成技术「体系化」
    linux quota磁盘限额,引发的rename系统调用 errno:18
    dnsperf
    stop容器,把信号量传给java进程,优雅退出
    JNA 调用操作系统函数 和 系统调用
    自顶向下深入分析Netty(五)--Future
    来测试下你的Java编程能力
    Netty笔记
  • 原文地址:https://www.cnblogs.com/qifeng1024/p/12636716.html
Copyright © 2011-2022 走看看