深拷贝(值拷贝)和浅拷贝(位拷贝)的区别
浅拷贝:就是对指针的拷贝,拷贝完成后,两个指针指向同一块内存地址空间;
深拷贝:不但是对指针的拷贝,而且对指针指向的内容进行拷贝,
拷贝完成之后的两个指针指向两块不同的内存空间。
浅拷贝容易出现的问题:
(1)浅拷贝只是对类中的简单数据成员进行赋值,当类的成员变量存在指针成员时,就会出现问题。
(2)在浅拷贝中由于obj1.m_data,obj2.m_data指向同一个内存空间,在delete obj1.m_data之后,该内存已经被释放(内存空间不可用),而obj2.m_data也指向它,它的内存空间已经释放,它就成为野指针,再去delete obj2.m_data的时候,就会出现内存泄漏,导致程序异常崩溃。
举例:
浅拷贝只是对类中的简单数据成员进行赋值,当类的成员变量存在指针成员时,就会出现问题。
#include <iostream>
#include <string.h>
using namespace std;
class A
{
private:
char *m_data; //定义私有变量指针
public:
A()
{
this->m_data = new char(12);
cout << "构造函数";
}
/*A(A &s)//自定义拷贝函数 { int length = strlen(s.m_data); m_data = new char(12); strcpy(m_data, s.m_data); cout << "拷贝构造"; }*/
~A() //自定义析构函数
{
if (this->m_data != NULL)
{
delete m_data;
m_data = NULL;
cout << "析构函数";
}
}
};
int main()
{
A obj1;
A obj2(obj1);
return 0;
}
分析:在自己未定义拷贝构造函数时,会调用体统默认的拷贝构造函数,实现浅拷贝,由于类里面存在指针成员,在de
深拷贝:类的成员变量存在指针的情况,所以不仅是拷贝的值的情况,而且也是给指针重新分配内存空间。
举例:
#include <iostream>
#include <string.h>
using namespace std;
class A
{
private:
char *m_data; //定义私有变量指针
public:
A()
{
this->m_data = new char(12);
cout << "构造函数";
}
A(A &s)//自定义拷贝函数
{
int length = strlen(s.m_data);
m_data = new char(12);
strcpy(m_data, s.m_data);
cout << "拷贝构造";
}
~A() //自定义析构函数
{
if (this->m_data != NULL)
{
delete m_data;
m_data = NULL;
cout << "析构函数";
}
}
};
int main()
{
A obj1;
A obj2(obj1);
return 0;
}
分析: 将自己定义的拷贝构造函数放开,就会完成深拷贝,其指针的地址对应不同的内存空间,所以执行析构函数时不会出错。
总结:当类中存在指针成员变量时,尽量自己定义拷贝构造函数,不去使用系统的默认拷贝构造函数,避免出现程序崩溃的问题。