浅拷贝就是让一个已经有的指针重新指向另一块已有的内存,而深拷贝则是重新分配一块内存,让一个指针指向它,然后把另一块内存中的数据拷贝到这个指针指向的内存中去。
例如:char *p;char *p1="jksgj";
p=p1;//此为浅拷贝
//深拷贝
int len=strlen[p1];
p=new char[len+1];
strcpy(p,p1);
使用浅拷贝在进行资源释放的时候,容易出现资源的重复释放而导致程序出错,所以一避免使用浅拷贝而使用深拷贝,例如在实现一个string类的构造函数中:
//MyString.h
#pragma once
class MyString
{
public:
MyString();
explicit MyString(char *data);
MyString(const MyString&other);
MyString(int n, char c);
MyString&operator=(const MyString&rgs);
~MyString();
private:
char*m_data;
};
//MyString.cpp
#include "stdafx.h"
#include "MyString.h"
#include <string.h>
MyString::MyString()
:m_data(NULL)
{
}
MyString::MyString( char*data)
// : m_data(data)不能浅拷贝,只能深拷贝
{
if (data == NULL)
{
m_data = new char[1];
m_data = '\0';
}
else
{
int len = strlen(data);
m_data = new char[len + 1];
// memset(m_data, 0, sizeof(m_data));可加可不加
strcpy(m_data, data);
}
}
MyString::MyString(int n, char c)
{
m_data = new char[n + 1];
for (int i = 0; i < n; i++)
m_data[i] = c;
}
//所有的成员变量都要进行一一的初始化
MyString::MyString(const MyString&other)
//:m_data(other.m_data)不能浅拷贝
{
int len = strlen(other.m_data);
m_data = new char[len + 1];
strcpy(m_data, other.m_data);
}
MyString&MyString::operator=(const MyString&rgs)
{
//1.判断是否相等,防止自我赋值
if (this == &rgs)
return *this;
//2.申请资源之前,一定要清理之前的资源
if (m_data != NULL)
{
delete[]m_data;
m_data = NULL;
}
//3.对所有成员的变量要一一赋值
int len = strlen(rgs.m_data);
m_data = new char[len + 1];
strcpy(m_data, rgs.m_data);
//4.返回一个对象的引用
return *this;
}
MyString::~MyString()
{
if (m_data != NULL)
{
delete[]m_data;
m_data = NULL;
}
}
如果再上面的代码处使用浅拷贝的话,如果在MyString::MyString( char*data)
// : m_data(data)不能浅拷贝,只能深拷贝
此处的data是指向动态分配的内存的话,此时经过参数化列表传参,则m_data和data必定指向同一块动态分配的内存,那么在析构函数中释放资源时delete []p,delete[]p1,
就会出现资源的重复释放,从而导致程序出错。