浅拷贝(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. [UE4]把工程升级到最新版本

    右键UE4工程文件,选择“Switch Unreal Engine version...” 确定后,再次双击打开工程升级到最新版本了.

  2. JAVA的非对称加密算法RSA——加密和解密

    原文转载至:https://www.cnblogs.com/OnlyCT/p/6586856.html 第一部分:RSA算法原理与加密解密 一.RSA加密过程简述 A和B进行加密通信时,B首先要生成一 ...

  3. freemarker ,DEFAULT_INCOMPATIBLE_IMPROVEMENTS 找不到

    一般出现这种问题的原因是,spring的版本和freemarker不匹配造成的~ nested exception is org.springframework.beans.factory.BeanC ...

  4. 浅析Spring框架之一(Spring简介)

    免责声明 本文为鄙人搜集网络资源并结合自己所思所得整理而成,如有侵权,敬请谅解. 何为spring框架 Spring是一个开源的轻量级控制反转(IoC)和面向切面(AOP)的容器框架. ◆目的:解决企 ...

  5. Web 单元测试

    问题描述: The import org.junit.Test conflicts with a type defined in the same file 导入的org.junit.Test和一个相 ...

  6. 第7章 进程关系(5)_贯穿案例2:mini shell(2)

    5. 贯穿案例2:mini shell(2) (1)己经完成的功能:pwd.cd.exit命令 (2)阶段性目标: ①env.export.echo及其他命令 ②标准输入.输出重定向"> ...

  7. Install hadoop on windows(non-virtual machine, such cygwin)

    DownloadBefore starting make sure you have this two softwares Hadoop 2.7.1 Java – Jdk 1.7+ Extract d ...

  8. CSS属性 table 的 border-collapse 边框合并

    说明 该CSS属性用来设定表格的行和列的边框是合并成单边框,还是分别有各自的边框 separate 缺省值.边框分开,不合并.collapse 边框合并.即如果相邻,则共用同一个边框. 虽然在DIV+ ...

  9. storm的定时任务

    应用场景: 第一种方法 参考代码StormTopologyTimer1.java package yehua.storm; import java.util.Map; import org.apach ...

  10. 常用模块:hashlib,subprocess,configparser。

    一  hashlib模块 那么我们前面学习数据类型的时候,也讲了hash,可变类型不可hash:不可变类型可hash. 我们知道hash是一种算法,接收传入的内容经过运算之后得到一个hash值,我们可 ...