您的位置:首页 > 编程语言 > C语言/C++

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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: