标签:
赋值运算符重载: 是用一个已经存在的对象去给另一个已经存在并初始化(调用过构造函数)的对象进行赋值。
拷贝构造函数:其实本质还是构造函数,用一个已存在的对象去构造一个原先不存在的对象。
string a("hello");
string b("world");
string c =a ; //拷贝构造函数
c = b; //调用赋值函数
一般来说是在数据成员包含指针对象的时候,应付两种不同的处理需求的 一种是复制指针对象,一种是引用指针对象
copy大多数情况下是复制,=则是引用对象的
例子:
class A
{
int nLen;
char * pData;
}
显然
A a, b;
a=b的时候,对于pData数据存在两种需求
第一种copy
a.pData = new char [nLen];
memcpy(a.pData, b.pData, nLen);
另外一种(引用方式):
a.pData = b.pData
一、拷贝构造函数
class CExample
{
public:
CExample(){pBuffer=NULL; nSize=0;}
~CExample(){delete pBuffer;}
void Init(int n){ pBuffer=new char[n]; nSize=n;}
private:
char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源
int nSize;
};
int main(int argc, char* argv[])
{
CExample theObjone;
theObjone.Init40);
//现在需要另一个对象,需要将他初始化称对象一的状态
CExample theObjtwo=theObjone;
...
}
语句"CExample theObjtwo=theObjone;"用theObjone初始化theObjtwo。
其完成方式是内存拷贝,复制所有成员的值。
完成后,theObjtwo.pBuffer==theObjone.pBuffer。
即它们将指向同样的地方,指针虽然复制了,但所指向的空间并没有复制,而是由两个对象共用了。这样不符合要求,对象之间不独立了,并为空间的删除带来隐患。
提供了拷贝构造函数后的CExample类定义为:
class CExample
{
public:
CExample(){pBuffer=NULL; nSize=0;}
~CExample(){delete pBuffer;}
CExample(const CExample&); //拷贝构造函数
void Init(int n){ pBuffer=new char[n]; nSize=n;}
private:
char *pBuffer; //类的对象中包含指针,指向动态分配的内存资源
int nSize;
};
CExample::CExample(const CExample& RightSides) //拷贝构造函数的定义
{
nSize=RightSides.nSize; //复制常规成员
pBuffer=new char[nSize]; //复制指针指向的内容
memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char));
}
浅拷贝与深拷贝
用一句简单的话来说就是:浅拷贝,只是对指针的拷贝,拷贝后两个指针指向同一个内存空间;深拷贝不但对指针进行拷贝,
而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
浅拷贝(位拷贝)会出现什么问题呢?
引起的问题:1:b.m_data 原有的内存未被释放,造成内存泄露
2:b.m_data和a.m_data指向同一块内存,a或b任何一方变动都会影响另一方,对象不独立了
3: 对象被析构是,m_data被析构两次。
实例分析:
后面部分转载:http://blog.csdn.net/feitianxuxue
浅拷贝:也就是在对象复制时,只是对对象中的数据成员进行简单的赋值,如果对象中存在动态成员,即指针,浅拷贝就会出现问题
#include <stdio.h>
class A
{
public:
A() // 构造函数,p指向堆中分配的一空间
{
m_data = new char(100);
printf("默认构造函数\n");
}
~A() // 析构函数,释放动态分配的空间
{
if(m_data != NULL)
{
delete m_data;
m_data = NULL;
printf("析构函数\n");
}
}
private:
char *m_data; // 一指针成员
};
int main()
{
A a;
A b(a); // 复制对象,出现问题
return 0;
}
深拷贝:对于深拷贝,针对成员变量存在指针的情况,不仅仅是简单的指针赋值,而是重新分配内存空间
#include <stdio.h>
#include <string>
class A
{
public:
A() // 构造函数,p指向堆中分配的一空间
{
m_pdata = new char(100);
printf("默认构造函数\n");
}
A(const A& r)
{
m_pdata = new char(100); // 为新对象重新动态分配空间
memcpy(m_pdata, r.m_pdata, strlen(r.m_pdata));
printf("copy构造函数\n");
}
~A() // 析构函数,释放动态分配的空间
{
if(m_pdata != NULL)
{
delete m_pdata;
printf("析构函数\n");
}
}
private:
char *m_pdata; // 一指针成员
};
int main()
{
A a;
A b(a); // 复制对象,不仅是数据成员的赋值,内存空间重分配
return 0;
}
标签:
原文地址:http://www.cnblogs.com/niupan369/p/4487142.html