栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++深拷贝与浅拷贝学习笔记

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++深拷贝与浅拷贝学习笔记

本博文源于C++基础,深拷贝与浅拷贝常常发生在C++中拷贝构造函数中,拷贝构造函数中,如果只是完成数据成员本身的复制,默认的拷贝构造函数也可以完成这种,如果复制的数据除了属性值本身之外,还有附加在属性值之外的额外内容,则需要自己编写拷贝构造函数。本博文基于此,演示了浅拷贝会发生的错误,并给出了一个深拷贝的应用场景。

文章目录
  • 1. 浅拷贝可能引发的错误
  • 2. 深拷贝应用案例--new开辟内存
  • 3.总结

1. 浅拷贝可能引发的错误
#include
#include
using namespace std;

class Car{
public:
    Car(char *con_pcarname,int con_seats); // 声明带参数的构造函数
    Car(Car &con_refcar); // 声明拷贝构造函数
    ~Car();

private:
    char *m_pCarName;
    int m_nSeats;

};

Car::Car(char *con_pcarname,int con_seats)
{
    int len = strlen(con_pcarname)  + 1;
    m_pCarName = new char[len];
    //向m_pCarName指向的空间中复制汽车名称
    strcpy_s(m_pCarName,len, con_pcarname);
    m_nSeats = con_seats;
}

Car::Car(Car &con_refcar)    //定义拷贝构造函数
{
    cout << "calling copy constructor" << endl;
    m_pCarName = con_refcar.m_pCarName;
    m_nSeats = con_refcar.m_nSeats;  //复制指针值
    cout << "end of copy constructor!" << endl;
}

Car::~Car()
{
    cout << "destructor is called!" << endl;
    delete[] m_pCarName; //释放 m_pCarName 指向的空间
}

int main()
{
    Car mynewcar("my new car",4);   //调用带参数的构造函数定义类对象
    Car myseccar(mynewcar);        //调用拷贝构造函数定义类对象
    return 0;

}


这里分别调用带参数的狗子哦啊函数与和拷贝构造函数创建两个对象menewcar,mysecar,mynewcar对象通过带参数的构造函数完成初始化,其中将n_pCarName指向一段new开辟的新空间,之后调用strcpy_s()函数将汽车名称存入。mysecar通过拷贝构造函数创建,在拷贝构造函数中只是对m_pCarName进行了指针值的复制,并没有使其指向独立空间,此时两个不同对象的m_pCarName指向的是同一块空间。
如果一旦析构,同一块空间就会被析构两次就会发生错误,因此这就是浅拷贝会带来的隐性错误。

2. 深拷贝应用案例–new开辟内存

在拷贝构造函数里,使用了new进行复制内存,完完整整的将数据复制出去,并提供独立的空间,而不是同一块空间,所以,将拷贝构造函数进行修改后,就不会发生同一块空间两次释放的错误。

#include
#include
using namespace std;
class Car{
public:
    Car(char *con_pcarname,int con_seats);// 声明带参数的构造函数
    Car(Car &con_refcar); // 声明拷贝构造函数
    ~Car();
private:
    char *m_pCarName;
    int m_nSeats;

};

Car::Car(char *con_pcarname,int con_seats) {
    int len = strlen(con_pcarname) + 1;
    m_pCarName = new char[len];

    //向m_pCarName指向的空间中复制汽车名称
    strcpy_s(m_pCarName, len, con_pcarname);
    m_nSeats = con_seats;
}
//定义拷贝构造函数
Car::Car(Car &con_refcars) {

    cout << "calling copy constructor!" << endl;
    int len = strlen(con_refcars.m_pCarName) + 1;
    m_pCarName = new char[len];  //m_pCarName 指向new开辟的空间
    strcpy_s(m_pCarName,len, con_refcars.m_pCarName);
    m_nSeats = con_refcars.m_nSeats;
    cout << "end of copy constructor!" << endl;
}


Car::~Car()  //定义析构函数
{
    static int i = 0;
    cout << "destructor is called!" << endl;
    delete[] m_pCarName;   //释放m_pCarName指向的空间
    if(i==1)
        system("pause");
    i++;
}

int main()
{
    Car mynewcar("my new car",4); //调用带参数的构造函数定义类对象
    Car myseccar(mynewcar);   //调用拷贝构造函数定义类对象
    return 0;

}

代码中,其中m_pCarName成员执行new开辟空间,这样不论掉用哪个构造函数都能保证每个对象的m_pCarName有独立空间,析构函数对每个对象执行delete操作都正确,程序正确执行。

3.总结

博文以深拷贝与浅拷贝在拷贝构造函数不同进行讲解,指出浅拷贝在指针指向值如果是同一个内存空间时会发生两次释放的错误,在修改后的深拷贝中,成功解决了问题,就不会发生这种问题。对内容和学习得到了进一步加深。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/587508.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号