浅拷贝和深拷贝
浅拷贝:如果一个类包含指针形式的成员变量,缺省的拷贝构造函数只是复制指针变量本身,而没有复制该指针所指向的内容,这种拷贝方式称为浅拷贝。
深拷贝:浅拷贝将导致不同对象间的数据共享,在delete时会引发"double free"异常。因此必须自己定义一个支持复制指针所指向内容的拷贝构造函数,即深拷贝。
#include <iostream>
using namespace std;
class Integer{
public:
Integer(int data):m_data(new int(data)){}
~Integer(void)
{
delete m_data;
m_data - NULL;
}
//缺省拷贝构造函数:浅拷贝
//Integer(const Integer& that):m_data(that.m_data){}
//自定义深拷贝构造函数
Integer(const Integer& that):m_data(new int(*that.m_data))
{
//m_data = new int(*that.m_data);
//*m_data = *that.m_data;
}
int get(void) const
{
return *m_data;
}
private:
int* m_data;
};
//测试用例
int main(void)
{
Integer i(100);
cout << i.get() << endl; //100
Integer i2(i);
cout << i2.get() << endl;
return 0;
}
实现String类
#include <iostream>
#include <cstring>
using namespace std;
class String{
public:
String(const char* str = ""):m_str(strcpy(new char[strlen(str) + 1],str)){}
~String(void)
{
delete[] m_str;
m_str = NULL;
}
//自定义深拷贝构造
String(const String& that):
m_str{strcpy(new char[strlen(that.m_str) + 1],that,m_str)}
//自定义深拷贝赋值函数
String& operator=(const String& that)
{
if(&tha != this)
{
char* str = new char[strlen(that.m_str) + 1];
delete[] m_str;
m_str = strcpy(str,that.m_str);
}
return *this;
}
const char* c_str(void) const
{
return m_str;
}
private:
char* m_str;
};
拷贝赋值
类的缺省拷贝赋值和缺省拷贝构造一样,是浅拷贝。为了得到深拷贝的效果,必须自定义拷贝赋值运算符函数。
拷贝赋值函数伪代码格式:
类名& operator=(const (类)类型& that)
{
if(this != &that) //防止自赋值
{
//1,分配新内存
//2,释放就内存
//3,拷贝数据到新内存
}
return *this; //4,返回自引用
}
一、字符串类型的深拷贝和浅拷贝赋值。
实现String类的深拷贝赋值函数
#include <iostream>
#include <cstring>
using namespace std;
class String{
public:
String(const char* str = ""):m_str(strcpy(new char[strlen(str) + 1],str)){}
~String(void)
{
delete[] m_str;
m_str = NULL;
}
//深拷贝
String(const String& that):m_str(strcpy(new char[strlen(that.m_str) + 1],that.m_str)){}
//编译器会为类提供一个浅拷贝赋值函数
//i2 = i3 -> i2.operator=(i3), 浅拷贝
/*String& operator=(const String& that)
{
m_str = that.m_str;
return *this; //返回自引用
}*/
//自定义深拷贝赋值
String& operator=(const String& that)
{
if(this != &that)
{
/* 基础版
m_str = new char[strlen(that.m_str) + 1];
strcpy(m_str,that.m_str);
*/
/*版本二,此版本先删除有风险,考虑new失败情况
delete[] m_str;
m_str = new char[strlen(that.m_str) + 1];
strcpy(m_str,that.m_str);
*/
//版本三
char* str = new char[strlen(that.m_str) + 1];
delete[] m_str;
m_str = strcpy(str,that.m_str);
/*版本四
String temp(that);
swap(m_str,temp.m_str);
*/
}
return *this;
}
const char* c_str(void) const
{
return m_str;
}
private:
char* m_str;
};
二、整型类型的深拷贝和深拷贝赋值
#include <iostream>
using namespace std;
class Integer{
public:
Integer(int data = 0):m_data(new int(data)){}
~Integer(void)
{
delete m_data;
m_data = NULL;
}
//拷贝构造函数
Integer(const Integer& that)
:m_data(new int(*that.m_data)){}
//深拷贝赋值函数
Integer& operator=(const Integer& that)
{
if(&that != this)
{
int* p_data = new int(*that.m_data);
delete m_data;
m_data = p_data;
}
return *this;
}
const int get(void) const
{
return *m_data;
}
private:
int* m_data;
};