C++学习基础七——深复制与浅复制
2016-09-09 00:12
183 查看
一、深复制与浅复制基本知识
深复制和浅复制,又称为深拷贝和浅拷贝。深复制和浅复制的区别如下图1所示:
图1
图1表示的是,定义一个类CDemo,包含int a和char *str两个成员变量,
当深复制时,A中的指针str与B中的指针str指向不同的地址,只是地址所指向的数据相同。
当浅复制时,A中的指针str与B中的指针str指向相同的地址。
1.浅复制:如果我们自己不实现复制构造函数,则C++会自动合成一个复制构造函数,又称为浅复制构造函数。
2.深复制:如果使用指针或者系统资源(如数据库,流对象等),则需要自己实现深复制的复制构造函数。
3.深复制与浅复制的代码区别:
Demo(const Demo &other) { this->id= other.id; this->str = new char[1024];//深复制 ,该指针与 other内的指针变量指向两个不同的地址,只是数据相同 strcpy(this->str,other.str); } 或者 Demo(const Demo &other) { this->id= other.id; //深复制 ,该指针与 other内的指针变量指向两个不同的地址,只是数据相同 this->str = other.str; } Demo(const Demo &other) { this->id= other.id; strcpy(this->str,other.str);//浅复制 }
4.如果自定义的类中包含指针,则应该自己实现深复制的复制构造函数,赋值操作符和析构函数。
二、管理指针成员
浅复制时因为两个指针指向相同的地址,很有可能出现野指针的情况;深复制不会出现野指针,但会出现很多相同的对象,浪费内存。
如何有效的使用指针成员呢?管理指针成员的三个方法如图2所示:
图2
三种方式的具体区别如图3所示:
图3
总结:智能指针其实是浅复制,只是智能指针不会产生野指针,而浅复制会产生野指针。
#include <iostream> using namespace std; class ADemo { public: ADemo(int v, const int &p) { val = v; ptr = new int(p); } ~ADemo() { delete ptr; } ADemo(const ADemo &other) { val = other.val; ptr = new int; *ptr = *other.ptr;//深复制 } ADemo& operator=(const ADemo &other) { val = other.val; ptr = new int; *ptr = *other.ptr;//深复制 return *this; } int get_ptr_val() { return *ptr; } void set_ptr(int v) { *ptr = v; } private: int val; int *ptr; }; class BDemo { public: BDemo(int v, const int &p) { val = v; ptr = new int(p); } ~BDemo() { delete ptr; } BDemo(const BDemo &other) { val = other.val; ptr = other.ptr;//浅复制 } BDemo& operator=(const BDemo &rig) { val = rig.val; ptr = rig.ptr;//浅复制 return *this; } int get_ptr_val() { return *ptr; } void set_ptr(int v) { *ptr = v; } private: int val; int *ptr; }; //====================智能指针start============ class U_Ptr { friend class CDemo; private: int *ptr; size_t use; U_Ptr(int *p,int u) { this->ptr = p; use = u; } ~U_Ptr() { delete ptr; } } ; class CDemo {//智能指针 public: CDemo(const int &p,int v) { ptr = new U_Ptr(new int(p),1); val = v; } ~CDemo() { if(--ptr->use == 0)delete ptr; } CDemo(const CDemo &other) { ++ptr->use;//多了一个对象使用 val = other.val; ptr = other.ptr;//浅复制 } CDemo& operator=(const CDemo &rig) { ++rig.ptr->use; if(--ptr->use == 0)delete ptr; val = rig.val; ptr = rig.ptr;//浅复制 return *this; } void set_Ptr_val(int v) { *ptr->ptr = v; } int get_ptr_val() { return *ptr->ptr; } private: int val; U_Ptr *ptr; }; void test_ShenCopy() { int prr = 20; ADemo a(10,prr); ADemo b = a; cout<<"a = "<<a.get_ptr_val()<<endl; cout<<"b = "<<b.get_ptr_val()<<endl; cout<<"修改之后:"<<endl; a.set_ptr(40); cout<<"a = "<<a.get_ptr_val()<<endl; cout<<"b = "<<b.get_ptr_val()<<endl; } void test_QianCopy() { int prr = 40; BDemo a(50,prr); BDemo b = a; cout<<"a = "<<a.get_ptr_val()<<endl; cout<<"b = "<<b.get_ptr_val()<<endl; cout<<"修改之后:"<<endl; b.set_ptr(80); cout<<"a = "<<a.get_ptr_val()<<endl; cout<<"b = "<<b.get_ptr_val()<<endl; } void test_smart() { int prr = 90; CDemo a(100,prr); CDemo b = a; cout<<"a = "<<a.get_ptr_val()<<endl; cout<<"b = "<<b.get_ptr_val()<<endl; cout<<"修改之后:"<<endl; b.set_Ptr_val(180); cout<<"a = "<<a.get_ptr_val()<<endl; cout<<"b = "<<b.get_ptr_val()<<endl; } int main() { cout<<"深复制:"<<endl; test_ShenCopy(); cout<<endl<<"浅复制:"<<endl; test_QianCopy(); cout<<endl<<"智能指针:"<<endl; test_smart(); return 0; }
相关文章推荐
- C++学习笔记——基础知识
- 《面向对象基础:C++实现》学习笔记之四
- Symbian C++学习之——菜单基础
- 学习笔记-C++搞Mobile基础
- C++学习笔记(一)--基础知识sizeof用法
- 回复:学习java必须有c++基础么?
- C++基础教程 学习笔记(二) 数组、字符串和指针
- C++/GDI+ 学习笔记(三)——基础
- C++ 基础小知识学习[1]
- C++基础(学习笔记)
- 《面向对象基础:C++实现》学习笔记之五
- C++学习(4)--基础知识(4)--关于const
- C++学习(3)--基础知识(3)--关于操作符的重载
- [MFC学习之C++基础] 孙鑫视频中第三讲中提到的小测试程序(关于基类和子类的继承关系)
- C++学习基础知识
- 《面向对象基础:C++实现》学习笔记之三
- C++学习笔记之(对象复制的困惑)
- 《面向对象基础:C++实现》学习笔记之八
- 智能指针:复制控制!《C++Primer 》第13章学习纪要
- C++基础教程 学习笔记(一) C++的数据类型和修饰符