浅拷贝(shallow copy)与深拷贝(deep copy)对于值拷贝的处理相同,都是创建新对象,但对于引用拷贝的处理不同,深拷贝将会重新创建新对象,返回新对象的引用字。浅拷贝不会创建新引用类型。

怎么判断一个类的赋值构造函数的方法:根据类的实现
1。如果它有一个用原生指针指针实现的对象引用,或是用boost::shared_ptr等引用分享所有权的智能指针实现的对象引用,则这个拷贝是浅拷贝
2。如果是用copy_ptr这种实现了深拷贝的智能指针实现的对象引用,就是深拷贝了。copy_ptr在内部保留一个指针,当它自己解析时,它同时也销毁它在内部保存的这个指针。
最能体现深层拷贝与浅层拷贝的,就是‘=’的重载。我们以此为例。
例1:浅拷贝
class string
{
char *m_str; //对象之中含有指针数据类型
public:
string(char *s)
{
m_str=s;
}
string(){};
string&operator=(const string s)
{
m_str=s.m_str; //s1,s2指向同一个内存
return *this}
};
int main()
{
string s1("abc"),s2;
s2=s1;
cout<<s2.m_str;
}
};
例2:深拷贝
string&operator=(const string&s)
{
if(strlen(m_str)!=strlen(s.m_str))
m_str=new char[strlen(s.m_str)+]; //为被赋值对象申请了一个新的内存
if(*this!=s)
strcmp(m_str,s.m_str);
return *this;
}
浅拷贝易使对象的值发生不必要的改变。这时我们需要智能shared_ptr指针来管理。
例:
#include <vector>
using namespace std;
using namespace boost; int main (int argc, const char * argv[])
{ typedef vector< shared_ptr > sharedContainers;
sharedContainers sharedArray();
int i=;
for(sharedContainers::iterator pos = sharedArray.begin() ;pos!=sharedArray.end();++pos)
{
*pos = make_shared(++i);
}
cout<<"sharedArray[5]的初始值:"<<*sharedArray[]<<endl;
cout<<"sharedArray[5]的初始引用计数为:"<<sharedArray[].use_count()<<endl;
shared_ptr p1 = sharedArray[];
*p1 = ;
cout<<"sharedArray[5]经过赋值后的值:"<<*sharedArray[]<<endl;
cout<<"sharedArray[5]赋值后的引用计数为:"<<sharedArray[].use_count()<<endl;
shared_ptr p2(sharedArray[]);
cout<<"sharedArray[5]复制后的引用计数为:"<<sharedArray[].use_count()<<endl;
return ;
}
其输出结果为:
  sharedArray[5]的初始值:6
  sharedArray[5]的初始引用计数为:1
  sharedArray[5]经过赋值后的值:10
  sharedArray[5]赋值后的引用计数为:2
  sharedArray[5]复制后的引用计数为:3
 
shared_ptr简单实现(主旨:引用计数reference count):

1.一个模板指针T* ptr,指向实际的对象。

2.创建类的新对象时,初始化指针并将引用计数置为1。

3.重载operator*和operator->,使得能像指针一样使用shared_ptr。

4.重载copy constructor,使其引用次数等于右操作数所指对象加一。

5.重载operator=,如果原来的shared_ptr已经有对象,则让其引用次数减一并判断引用是否为零(是否调用delete)。

 然后将新的对象引用次数加一。

6.重载析构函数,使引用次数减一并判断引用是否为零(是否调用delete)。

#ifndef __SHARED_PTR_
#define __SHARED_PTR_ template <typename T>
class shared_ptr {
public:
shared_ptr(T* p) : count(new int()), _ptr(p) {}
shared_ptr(shared_ptr<T>& other) : count(&(++*other.count)), _ptr(other._ptr) {}
T* operator->() { return _ptr; }
T& operator*() { return *_ptr; }
shared_ptr<T>& operator=(shared_ptr<T>& other)
{
++*other.count;
if (this->_ptr && == --*this->count)
{
delete count;
delete _ptr;
}
this->_ptr = other._ptr;
this->count = other.count;
return *this;
}
~shared_ptr()
{
if (--*count == )
{
delete count;
delete _ptr;
}
}
int getRef() { return *count; }
private:
int* count;
T* _ptr;
}; #endif

C++中的浅拷贝和深拷贝的更多相关文章

  1. 【转】JAVA中的浅拷贝和深拷贝

    原文网址:http://blog.bd17kaka.net/blog/2013/06/25/java-deep-copy/ JAVA中的浅拷贝和深拷贝(shallow copy and deep co ...

  2. js中的浅拷贝和深拷贝

    说说最近所学:浅拷贝和深拷贝也叫做浅克隆和深克隆,深浅主要针对的是对象的"深度",常见的对象都是"浅"的,也就是对象里的属性就是单个的属性,而"深&q ...

  3. Javascript中的浅拷贝和深拷贝

    很多开发语言中都有浅拷贝和深拷贝的说法,这里简单区分一下它们在Javascript中的区别,以及jQuery中深拷贝的实现. 在谈浅拷贝和深拷贝之前,先要屡清楚Javascript中的按值访问和按引用 ...

  4. 浅谈JS中的浅拷贝与深拷贝

    前端工程师应该都比较熟悉浅拷贝和深拷贝的概念,在日常业务代码的过程中,特别是做数据处理的时候,经常行的会遇到,比如如何在不修改原对象的基础上,重新生成一个一模一样的对象,加以利用,又或是,如何巧妙地运 ...

  5. javascript中的浅拷贝和深拷贝(拷贝引用和拷贝实例)

    作者:千锋教育链接:https://www.zhihu.com/question/23031215/answer/326129003来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  6. C# 中的浅拷贝与深拷贝

    Ø  简介 在 C# 中分为两种数据类型,值类型和引用类型.我们知道,值类型之间赋值是直接将值赋值给另一个变量,两个变量值的改变都互不影响:而引用类型赋值则是将引用赋值给另一个变量,其中一个变量中的成 ...

  7. JS中的浅拷贝与深拷贝

    浅拷贝与深拷贝的区别: 浅拷贝: 对基本类型和引用类型只进行值的拷贝,即,拷贝引用对象的时候,只对引用对象的内存地址拷贝,新旧引用属性指向同一个对象,修改任意一个都会影响所有引用当前对象的变量. 深拷 ...

  8. java中的浅拷贝和深拷贝

    复制 将一个对象的引用复制给另一个对象,一共有三种方式.第一种方式是直接赋值,第二种方式是浅复制,第三种方式是深复制. 1.直接赋值 在Java中,A a1 = a2,这实际上复制的是引用,也就是说 ...

  9. python中的浅拷贝,深拷贝

    直接引用,间接引用 # 1.列表存储的是索引对应值的内存地址,值会单独的开辟一个内存空间 list = ["a","b"] 内存里面存储的就是list[0],l ...

  10. Objective-C中的浅拷贝和深拷贝(转载)

    本文转自:http://segmentfault.com/blog/channe/1190000000604331 浅拷贝 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间.如: ...

随机推荐

  1. R语言学习——欧拉计划(3)Largest prime factor 求最大质因数

    The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 60085 ...

  2. 如果安装提示缺少某vistal c++ 装完仍然报错,可以尝试

    https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python 从这个网站直接下载需要的包进行安装 来源 https://www.cnblogs.co ...

  3. 1092 To Buy or Not to Buy (20 分)

    1092 To Buy or Not to Buy (20 分) Eva would like to make a string of beads with her favorite colors s ...

  4. 将ESXI所有的端口组迁移到分布式交换机的步骤

    1.如果是DELL服务器,一般有2-4个网口,那么所有的网口都把网线插到交换机上:2.DELL安装ESXI系统,根据不同的DELL硬件,要安装不同的ESXI版本.原则上越高版本,支持的硬件越多向下兼容 ...

  5. Oracle跨库复制表结构

    1.首先建立远程连接 create public database link LINK_SJPSconnect to system identified by manager using '(DESC ...

  6. Ubuntu14.04下hadoop-2.6.0单机配置和伪分布式配置

    需要重新编译的教程:http://blog.csdn.net/ggz631047367/article/details/42460589 在Ubuntu下创建hadoop用户组和用户 hadoop的管 ...

  7. iOS TTF文件改变字体

    TTF(True Type Font):是一种字库名称 TTF文件:是Apple公司和Microsoft公司共同推出的字体文件格式 使用: 1 获取字体文件 从各种渠道下载字体ttf,网站或从别的ip ...

  8. php while循环控制实例讲解

    while循环是PHP中最简单的循环,其基本格式为: while (expr){ statement } 或者 while (expr): statement endwhile; 该语法表示,只要ex ...

  9. 小朋友学C语言(7)

    数组 一.数组简介 C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合.数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量. 数组的声明并不是声明一个个单独的变量,比 ...

  10. ORM介绍(字段 和 字段的参数)

    ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...