C++浅拷贝与深拷贝
Bright-SKY 人气:0类中有指针成员 才会讨论 浅拷贝 和深拷贝问题。
浅拷贝(单纯值拷贝)
#include <iostream> #include <string.h> #include <stdlib.h> using namespace std; class Person { public: char *m_name; public: Person(char *name) { cout<<"有参构造"<<endl; m_name = (char *)calloc(1,strlen(name)+1); if(m_name == NULL) { cout<<"空间申请失败"<<endl; exit(-1); } strcpy(m_name, name); } ~Person() { cout<<"析构函数"<<endl; //释放指针成员 指向的堆区空间 if(m_name != NULL) { free(m_name); m_name = NULL; } cout<<"-----001------"<<endl; } }; int main(int argc, char *argv[]) { Person ob1("lucy"); Person ob2 = ob1;//拷贝构造(默认是浅拷贝) cout<<"ob2.m_name = "<<ob2.m_name<<endl; return 0; }
深拷贝
必须在拷贝构造中给ob2.m_name申请空间
#include <iostream> #include <string.h> #include <stdlib.h> using namespace std; class Person { public: char *m_name; public: Person(char *name) { cout<<"有参构造"<<endl; m_name = (char *)calloc(1,strlen(name)+1); if(m_name == NULL) { cout<<"空间申请失败"<<endl; exit(-1); } strcpy(m_name, name); } Person(const Person &ob) { cout<<"拷贝构造函数(深拷贝)"<<endl; m_name = (char *)calloc(1, strlen(ob.m_name)+1); if(m_name == NULL) { cout<<"空间申请失败"<<endl; exit(-1); } strcpy(m_name, ob.m_name); } ~Person() { cout<<"析构函数"<<endl; //释放指针成员 指向的堆区空间 if(m_name != NULL) { free(m_name); m_name = NULL; } } }; int main(int argc, char *argv[]) { Person ob1("lucy"); Person ob2 = ob1;//拷贝构造 cout<<"ob2.m_name = "<<ob2.m_name<<endl; return 0; }
总结
1、如果类中的成员 指向了堆区空间 一定要记得在析构函数中 释放该空间
2、如果用户 不实现 拷贝构造 系统就会提供默认拷贝构造,而默认拷贝构造 只是单纯的赋值 容易造成浅拷贝问题
3、用户记得 要实现:无参构造(初始化数据)、有参构造(赋参数)、拷贝构造(深拷贝) 、析构函数(释放空间)
拷贝构造函数的调用时机
拷贝构造函数调用的时机:旧对象 给新对象 初始化
class Data { public: Data() { cout<<"无参构造"<<endl; } Data(const Data &ob) { cout<<"拷贝构造"<<endl; } ~Data() { cout<<"析够函数"<<endl; } };
情形1:旧对象给新对象初始化
Data ob1; Data ob2 = ob1;//调用拷贝构造
情形2:普通对象作为函数的参数
void fun01(Data ob)//Data ob=ob1 发生拷贝构造 { } int main(int argc, char *argv[]) { Data ob1; fun01(ob1); return 0; }
情形3:普通对象 作为函数的返回值
#include <iostream> using namespace std; Data fun01(void) { Data ob1; return ob1; } int main(int argc, char *argv[]) { Data ob = fun01(); return 0; }
vs下会发生拷贝构造:
Qt、linux不会发生拷贝:
加载全部内容