您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > C++拷贝构造函数(深拷贝,浅拷贝)
C++拷贝构造函数深拷贝,浅拷贝无错误的浅拷贝先看一个简单的例子,该例子是浅拷贝的典型代表,而且没有问题。接下来看Example1。Cperson.h#ifndef_CPERSON_H#define_CPERSON_HclassCperson{public:Cperson(intage);voidPrint(void);private:intm_age;};#endifCperson.cpp#includeCperson.h#includeiostream.hCperson::Cperson(intage):m_age(age){}voidCperson::Print(void){coutMyageism_ageendl;}Main.cpp#includeCperson.h#includeiostream.hvoidmain(void){CpersonTom(10);Tom.Print();CpersonJim(Tom);Jim.Print();}结果结果分析对于语句CpersonJim(Tom),我们并没有定义相应的拷贝构造函数,编译器将会自动生成一个默认的拷贝构造函数。默认拷贝构造函数所做的工作是,将一个对象的全部数据成员赋值给另一个对象的数据成员。C++把只对象数据成员简单赋值这种情况称为“浅拷贝”。结果分析听起来,编译器似乎很好,会提供一个我们没有定义的拷贝构造函数,但这后面存在巨大的风险。所以有些事情(拷贝构造函数)还是自力更生不接受外援的好。有错误的浅拷贝在接下来的Example2中,我们将看到浅拷贝带来的错误。Cperson.h#ifndef_CPERSON_H#define_CPERSON_HclassCperson{public:Cperson(intage,char*name);~Cperson();voidPrint(void);private:intm_age;char*m_name;};#endifCperson.cpp#includeCperson.h#includeiostream.h#includestring.hCperson::Cperson(intage,char*name){m_name=newchar[strlen(name)+1];if(m_name!=NULL){strcpy(m_name,name);}m_age=age;coutm_name的构造函数endl;}Cperson.cppCperson::~Cperson(){cout析构姓名:m_nameendl;if(m_name!=NULL){deletem_name;}}voidCperson::Print(void){coutMyageism_age,Mynameism_nameendl;}Main.cpp#includeCperson.h#includeiostream.hvoidmain(void){CpersonTom(10,Tom);Tom.Print();CpersonJim(Tom);Jim.Print();}结果结果分析可以看到,程序出现了错误。在执行语句CpersonTom(10,“Tom”)时,用new动态开辟了一段内存,用来存放”Tom”。在执行CpersonJim(Tom)时,只是将Tom的成员(Tom.m_age,Tom.m_name)赋值给Jim相应的成员。结果分析此时,Tom.m_name和Jim.m_name指向同一内存空间,然而,系统并没给Jim.m_name开辟相应的内存空间。执行完Jim.Print()后,开始执行析构函数,析构函数的执行顺序和对象构造函数的执行顺寻相反,所以先执行Jim的析构函数,执行完Jim的析构函数后,Jim.m_name所指的内存空间已经释放。结果分析接着执行Tom的析构函数,此时就会出现问题,即在释放Tom.m_name所指的内存空间时会出现问题,因为这段内存空间在Jim的析构函数中已经释放过了。出现这种原因的根本在于“浅拷贝”,所以需要定义自己的构造函数。深拷贝接下来看Example3,在该例子中执行深拷贝。Cperson.h#ifndef_CPERSON_H#define_CPERSON_HclassCperson{public:Cperson(intage,char*name);Cperson(Cperson&per);~Cperson();voidPrint(void);private:intm_age;char*m_name;};#endifCperson.cpp#includeCperson.h#includeiostream.h#includestring.hCperson::Cperson(intage,char*name){m_name=newchar[strlen(name)+1];if(m_name!=NULL){strcpy(m_name,name);}m_age=age;coutm_name的构造函数endl;}Cperson.cppCperson::Cperson(Cperson&per){m_name=newchar[strlen(per.m_name)+1];if(m_name!=NULL){strcpy(m_name,per.m_name);}m_age=per.m_age;coutm_name的拷贝构造函数endl;}Cperson.cppCperson::~Cperson(){cout析构姓名:m_nameendl;if(m_name!=NULL){deletem_name;}}voidCperson::Print(void){coutMyageism_age,Mynameism_nameendl;}Main.cpp#includeCperson.h#includeiostream.hvoidmain(void){CpersonTom(10,Tom);Tom.Print();CpersonJim(Tom);Jim.Print();}结果分析结果分析可以看到,自己定义了拷贝构造函数后,就没有问题了浅拷贝和深拷贝深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。在实际中应该避免浅拷贝。
本文标题:C++拷贝构造函数(深拷贝,浅拷贝)
链接地址:https://www.777doc.com/doc-3972273 .html