浅拷贝(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. 杂项-Java:jar 包与 war 包介绍与区别

    ylbtech-杂项-Java:jar 包与 war 包介绍与区别 1.返回顶部 1. 做Java开发,jar包和war包接触的挺多的,有必要对它们做一个深入的了解,特总结整理如下: 1.jar包的介 ...

  2. [转]IE6 的浮动

    IE6 的一个 BUG,(IE6 双倍边距 BUG),只要满足下面 3 个条件才会出现这个 BUG: 1)要为块状元素: 2)要左侧浮动: 3)要有左外边距(margin-left): 解决这个 BU ...

  3. [转]Java 运算符的优先级

    Java 运算符的优先级(从高到低) 优先级 描述 运算符 1 括号 ().[] 2 正负号 +.- 3 自增自减,非 ++.--.! 4 乘除,取余 *./.% 5 加减 +.- 6 移位运算 &l ...

  4. CentOS命令行性能检测工具

    一.uptime Uptime命令的显示结果包括服务器已经运行了多长时间,有多少登陆用户和对服务器性能的总体评估(load average).load average值分别记录了上个1分钟,5分钟和1 ...

  5. [UE4]C++ STL总结

    STL概述 STL (Standard Template Library, 标准模板库) 是惠普实验室开发的一系列软件的统称.主要核心分为三大部分:容器(container).算法(algorithm ...

  6. C#后台调用前台javascript的五种方法小结

    第一种,OnClientClick (vs2003不支持这个方法) <asp:Button ID="Button1" runat="server" Tex ...

  7. 普适注意力:用于机器翻译的2D卷积神经网络,显著优于编码器-解码器架构

    现有的当前最佳机器翻译系统都是基于编码器-解码器架构的,二者都有注意力机制,但现有的注意力机制建模能力有限.本文提出了一种替代方法,这种方法依赖于跨越两个序列的单个 2D 卷积神经网络.该网络的每一层 ...

  8. XPath 常用语法札记

    * 不包含属性的元素 例如不包含属性的span: span[not(@*)] * 文本包含某部分的元素 例如文本包含Rank的元素: *[contains(text(),'Rank')] * 选择匹配 ...

  9. 简单工厂法( Factory Method)

    工厂方法 (Factory Method) Define an interface for creating an object ,but let subclasses decide which cl ...

  10. RedHat7.0更新yum源

    https://blog.csdn.net/hongbin_xu/article/details/79316614