美文网首页
[C++之旅] 15 深拷贝与浅拷贝

[C++之旅] 15 深拷贝与浅拷贝

作者: Onicc | 来源:发表于2018-11-24 23:04 被阅读0次

    [C++之旅] 15 深拷贝与浅拷贝

    • 拷贝构造函数分为深拷贝和浅拷贝两种方式
    • 浅拷贝只是将被拷贝的对象的成员直接赋值给拷贝的对象,如对象中包含指针,则拷贝的对象与被拷贝的对象中的指针指向的为同一个地址。
    • 面对对象中的指针,深拷贝则重新开辟内存,复制拷贝指针中的数据。

    浅拷贝实例

    main.cpp

    #include <iostream>
    #include "team.h"
    
    using namespace std;
    
    int main()
    {
        Team team1(12);
    
        Team team2(team1);
    
        cout << "team1.num = " << team1.getnum() << endl;
        cout << "team2.num = " << team2.getnum() << endl;
    
        team1.printageAddr();
        team2.printageAddr();
    
        return 0;
    }
    

    Team.cpp

    #include <iostream>
    #include "team.h"
    
    using namespace std;
    
    Team::Team(int num) : m_num(num)
    {
        //给m_age分配m_num个int的内存
        m_age = new int[m_num];
        cout<< "Team" <<endl;
    }
    Team::Team(const Team &team)
    {
        m_age = team.m_age;
        m_num = team.m_num;
        cout<< "Team &" <<endl;
    }
    
    Team::~Team()
    {
        delete []m_age;
        m_age = NULL;
        cout<< "~Team" <<endl;
    }
    
    void Team::setnum(int num)
    {
        m_num = num;
    }
    
    int Team::getnum()
    {
        return m_num;
    }
    
    void Team::printageAddr()
    {
        cout << "m_age's address is " << m_age << endl;
    }
    

    Team.h

    #ifndef __TEAM_H__
    #define __TEAM_H__
    
    class Team
    {
    public:
        Team(int num);
        Team(const Team &team);
        ~Team();
        void setnum(int num);
        int getnum();
        void printageAddr();
    private:
        int m_num;
        int *m_age;
    };
    
    
    #endif
    

    运行结果:

    Team
    Team &
    team2.num = 12
    m_age's address is 0x7fb939402750
    m_age's address is 0x7fb939402750
    ~Team
    a.out(2560,0x7fffb8419380) malloc: *** error for object 0x7fb939402750: pointer being freed was not allocated
    *** set a breakpoint in malloc_error_break to debug
    

    浅拷贝后m_age指针指向的是同一个位置,但是在释放m_age内存时,会释放两次,释放team1时释放一次0x7fb939402750,释放team2时会释放第二次,因此会出现最后几句话的错误信息。

    深拷贝

    main.cpp

    #include <iostream>
    #include "team.h"
    
    using namespace std;
    
    int main()
    {
        Team team1(12);
    
        Team team2(team1);
    
        cout << "team1.num = " << team1.getnum() << endl;
        cout << "team2.num = " << team2.getnum() << endl;
    
        team1.printageAddr();
        team2.printageAddr();
    
        team1.printage();
        team2.printage();
    
        return 0;
    }
    

    Team.cpp

    #include <iostream>
    #include "team.h"
    
    using namespace std;
    
    Team::Team(int num) : m_num(num)
    {
        //给m_age分配m_num个int的内存
        m_age = new int[m_num];
        for(int i = 0; i < m_num; i++)
            *(m_age + i) = i;
        cout<< "Team" <<endl;
    }
    Team::Team(const Team &team)
    {
        m_num = team.m_num;
        m_age = new int[m_num];
        for(int i = 0; i < m_num; i++) {
            *(m_age + i) = *(team.m_age + i);
            //m_age[i] = team.m_age[i];
        }
    
        cout<< "Team &" <<endl;
    }
    
    Team::~Team()
    {
        delete []m_age;
        m_age = NULL;
        cout<< "~Team" <<endl;
    }
    
    void Team::setnum(int num)
    {
        m_num = num;
    }
    
    int Team::getnum()
    {
        return m_num;
    }
    
    void Team::printageAddr()
    {
        cout << "m_age's address is " << m_age << endl;
    }
    
    void Team::printage()
    {
        for(int i = 0; i < m_num; i++)
            cout << *(m_age + i);
        cout << endl;
    }
    

    Team.h

    #ifndef __TEAM_H__
    #define __TEAM_H__
    
    class Team
    {
    public:
        Team(int num);
        Team(const Team &team);
        ~Team();
        void setnum(int num);
        int getnum();
        void printageAddr();
        void printage();
    private:
        int m_num;
        int *m_age;
    };
    
    
    #endif
    

    运行结果:

    Team
    Team &
    team1.num = 12
    team2.num = 12
    m_age's address is 0x7fc53c402750
    m_age's address is 0x7fc53c402780
    01234567891011
    01234567891011
    ~Team
    ~Team
    

    在上一个程序的基础上,修改了拷贝构造函数,拷贝指针变量时,先申请内存再对每个地址的值进行复制,并将指针的地址以及地址的内容输出,如上结果所示,两个地址不相同,但其内容相同,而且编译器没有报错哦。

    相关文章

      网友评论

          本文标题:[C++之旅] 15 深拷贝与浅拷贝

          本文链接:https://www.haomeiwen.com/subject/mrduqqtx.html