一、深复制与浅复制基本知识

深复制和浅复制,又称为深拷贝和浅拷贝。
深复制和浅复制的区别如下图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[];//深复制 ,该指针与 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),);
val = v;
}
~CDemo()
{
if(--ptr->use == )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 == )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 = ;
ADemo a(,prr);
ADemo b = a;
cout<<"a = "<<a.get_ptr_val()<<endl;
cout<<"b = "<<b.get_ptr_val()<<endl;
cout<<"修改之后:"<<endl;
a.set_ptr();
cout<<"a = "<<a.get_ptr_val()<<endl;
cout<<"b = "<<b.get_ptr_val()<<endl;
}
void test_QianCopy()
{ int prr = ;
BDemo a(,prr);
BDemo b = a;
cout<<"a = "<<a.get_ptr_val()<<endl;
cout<<"b = "<<b.get_ptr_val()<<endl;
cout<<"修改之后:"<<endl;
b.set_ptr();
cout<<"a = "<<a.get_ptr_val()<<endl;
cout<<"b = "<<b.get_ptr_val()<<endl;
} void test_smart()
{
int prr = ;
CDemo a(,prr);
CDemo b = a;
cout<<"a = "<<a.get_ptr_val()<<endl;
cout<<"b = "<<b.get_ptr_val()<<endl;
cout<<"修改之后:"<<endl;
b.set_Ptr_val();
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 ;
}

C++学习基础七——深复制与浅复制的更多相关文章

  1. Python学习日记之字典深复制与浅复制

    Python中通过copy模块有两种复制(深复制与浅复制) copy 浅复制 复制时只会复制父对象,而不会复制对象的内部的子对象. deepcopy 深复制 复制对象及其子对象 因此,复制后对原dic ...

  2. C#深复制和浅复制

    本文在于巩固基础 我们来看看什么是深复制.浅复制: C#中对于数据的复制机制虽然简单但是容易让人误解.C#数据类型大体分为值类型(value type)与引用类型(reference type).对于 ...

  3. .Net深复制、浅复制

    在.Net,大家都知道引用类型的深复制.浅复制吧. ,一般int等值类型是值类型(复制时是直接传值),一般的类(List<T>,Class)是引用类型(复制时传地址),默认是浅复制.若ob ...

  4. php对象当参数传递 && php深复制和浅复制

    把对象当参数传递给方法,在方法里改过对象后,影响到外面的对象  因为对象是引用传递过去的 class Book { public $name; public function __construct( ...

  5. iOS 集合的深复制与浅复制

    概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 一图以蔽之 再简单些说:浅复制就是指针拷贝:深复制 ...

  6. Java中对象的深复制和浅复制详解

    1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...

  7. Java中的深复制与浅复制

    1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不 复制它所引用的对象. ...

  8. C#深复制与浅复制

    C#深复制与浅复制 C#中对于数据的复制机制虽然简单但是容易让人误解.C#数据类型大体分为值类型(value type)与引用类型(reference type).对于值类型数据,复制的时候直接将数据 ...

  9. clone()方法、深复制和浅复制

    clone方法 Java中没有明确提供指针的概念和用法,而实质上没个new语句返回的都是一个指针的引用,只不过在大部分情况下开发人员不需要关心如何去操作这个指针而已. 在实际编程中,经常会遇到从某个已 ...

随机推荐

  1. jsonp 实现sso

    这几天用jsop实现了公司的sso. 这里面最重要的是对cookie的理解. cookie 就是一个网站存于本地的数据,zai下次请求同一个网站时,发送给服务器,服务器端可以进行AUD操作,这种操作后 ...

  2. ubunut 14.04 将Caps Lock设置为Control

    入手了emacs,一直折腾想把caps Lock设置为control键. 网上看到一个用gnome里找到系统-首选项之类可以直接设置的.在14.04版的ub中是找不到的(新版设置太坑,只有那么几个选项 ...

  3. uva 10622

    http://vjudge.net/contest/140673#problem/H 求某个数字(最大到10^9,可为负值)写成完全p次方数的指数p是多少 分析: 先进行唯一分解,之后p整除各个素因子 ...

  4. mysql主从复制问题之主从两端binlog日志不同步解决方案

    主操作: 进入主的数据库查看状态: mysql> show master statusG; *************************** 1. row **************** ...

  5. 一些鲜为人知却非常实用的数据结构 - Haippy

    原文:http://www.udpwork.com/item/9932.html 作为程序猿(媛),你必须熟知一些常见的数据结构,比如栈.队列.字符串.链表.二叉树.哈希,但是除了这些常见的数据结构以 ...

  6. linux网络编程-(socket套接字编程UDP传输)

    今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中, ...

  7. eclipse美化

    // */ // ]]>   eclipse美化 Table of Contents 1 中文字体 2 皮肤 3 emacs+ 1 中文字体 win7下打开eclipse3.7中文字体很小,简直 ...

  8. springmvc的xml版本和注解版本

    感觉还是注解方式比较实用 xml方式 web.xml <!-- 读取spring mvc的核心配置文件 --> <servlet> <servlet-name>yx ...

  9. Correlation Filter in Visual Tracking系列二:Fast Visual Tracking via Dense Spatio-Temporal Context Learning 论文笔记

    原文再续,书接一上回.话说上一次我们讲到了Correlation Filter类 tracker的老祖宗MOSSE,那么接下来就让我们看看如何对其进一步地优化改良.这次要谈的论文是我们国内Zhang ...

  10. (C#) 反转字符串,反转一个句子中单词。

    这个是非常基本的一道面试题,但是要考虑周全. 首先反转一个字符串: 基本思路是变成Char数组,然后调用C#里面的方法,或者设定两个index,从头,尾向中间遍历,并交换. 方法一: Array.Re ...