本博文源于C++基础,深拷贝与浅拷贝常常发生在C++中拷贝构造函数中,拷贝构造函数中,如果只是完成数据成员本身的复制,默认的拷贝构造函数也可以完成这种,如果复制的数据除了属性值本身之外,还有附加在属性值之外的额外内容,则需要自己编写拷贝构造函数。本博文基于此,演示了浅拷贝会发生的错误,并给出了一个深拷贝的应用场景。
- 1. 浅拷贝可能引发的错误
- 2. 深拷贝应用案例--new开辟内存
- 3.总结
#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指向的是同一块空间。
如果一旦析构,同一块空间就会被析构两次就会发生错误,因此这就是浅拷贝会带来的隐性错误。
在拷贝构造函数里,使用了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.总结博文以深拷贝与浅拷贝在拷贝构造函数不同进行讲解,指出浅拷贝在指针指向值如果是同一个内存空间时会发生两次释放的错误,在修改后的深拷贝中,成功解决了问题,就不会发生这种问题。对内容和学习得到了进一步加深。



