我们可以定义拷贝操作,使类的行为看起来像一个值或者像一个指针,这取决于如何拷贝指针成员。

当我们拷贝一个像值的对象时,副本和原对象是完全独立的,改变副本不会对原对象有任何影响,反之亦然。标准库容器和string类的行为像一个值。

当我们拷贝一个行为像指针的类的对象时,副本和原对象使用相同的底层数据,改变副本也会改变原对象,反之亦然。

浅拷贝,指的是在对象复制时,只是对对象中的数据成员进行简单的赋值,默认拷贝构造函数执行的也是浅拷贝。这样一来可能出现多个指针指向同一块内存的情况

在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间

一、行为像值的类(不同的类对象的指针数据成员指向独立的内存空间)

class HasPtr
{
public:
HasPtr(const HasPtr&) :ps(new string(*p.ps), i(p.i)){}
HasPtr& operator=(const HasPtr &);
~HasPtr(){ delete ps; }
private:
string *ps;
int i;
};
/*
通过先拷贝右侧运算对象,我们可以处理自赋值情况,并能保证异常发生时代码安全。
注意:1、返回值 2、自赋值 3、new异常。 解决方案:返回引用,先判断是否自赋值,若是则返回,在释放旧内存前先分配好内存
*/
HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
auto newp = new string(*rhs.ps);//拷贝底层string
delete ps;//释放旧内存
ps = newp;
i = rhs.i;
//处理连锁赋值
return *this;
} HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
delete ps;//释放旧内存
//如果rhs和*this是同一个对象,我们就将从已释放的内存中拷贝数据
ps = new string(*rhs.ps);
i = rhs.i;
return *this;
}

二、定义行为像指针的类(多个类对象的指针指向同一个地址,但不能出现错误)

因为可能会有多个类的指针指向同一个地址,所以使用引用计数,引用计数是个指针,如果是个值得话,考虑下面情况(值得话每个对象都保存一个副本,互相独立)。

HasPtr p1("ljy");

HasPtr p2(p1);

HasPtr p3(p1);//p1,p2,p3指向相同的string,若引用计数是值的话,无法更新

class HasPtr
{
private:
string *ps;
int i;
int *use;
public:
HasPtr(const HasPtr &p) :ps(p.ps), i(p.i), use(p.use){ ++*use; }
HasPtr& operator=(const HasPtr&);
~HasPtr();
}; HasPtr::~HasPtr()
{
if (--*use == )
{
delete ps;
delete use;
}
} HasPtr& HasPtr::operator=(const HasPtr &rhs)
{
//先++rhs.use,可以处理自赋值的情况
++*rhs.use;
if (--*use == )
{
delete ps;
delete use;
}
ps = rhs.ps;
i = rhs.i;
use = rhs.use;
return *this;
}

【c++】拷贝控制具体分析的更多相关文章

  1. C++ Primer : 第十三章 : 拷贝控制之对象移动

    右值引用 所谓的右值引用就是必须将引用绑定到右值的引用,我们通过&&来绑定到右值而不是&, 右值引用只能绑定到即将销毁的对象.右值引用也是引用,因此右值引用也只不过是对象的别名 ...

  2. C++ Primer : 第十三章 : 拷贝控制之拷贝控制和资源管理

    定义行为像值的类 行为像值的类,例如标准库容器和std::string这样的类一样,类似这样的类我们可以简单的实现一个这样的类HasPtr. 在实现之前,我们需要: 定义一个拷贝构造函数,完成stri ...

  3. C++的那些事:类的拷贝控制

    1,什么是类的拷贝控制 当我们定义一个类的时候,为了让我们定义的类类型像内置类型(char,int,double等)一样好用,我们通常需要考下面几件事: Q1:用这个类的对象去初始化另一个同类型的对象 ...

  4. C++ Primer : 第十三章 : 拷贝控制之拷贝、赋值与销毁

    拷贝构造函数 一个构造函数的第一个参数是自身类类型的引用,额外的参数(如果有)都有默认值,那么这个构造函数是拷贝构造函数.拷贝构造函数的第一个参数必须是一个引用类型. 合成的拷贝构造函数   在我们没 ...

  5. Chapter13:拷贝控制

    拷贝控制操作:拷贝构造函数.拷贝赋值运算符.移动构造函数.移动赋值运算符.析构函数. 实现拷贝控制操作的最困难的地方是首先认识到什么时候需要定义这些操作. 拷贝构造函数: 如果一个构造函数的第一个参数 ...

  6. C++ 拷贝控制和资源管理,智能指针的简单实现

    C++ 关于拷贝控制和资源管理部分的笔记,并且介绍了部分C++ 智能指针的概念,然后实现了一个基于引用计数的智能指针.关于C++智能指针部分,后面会有专门的研究. 通常,管理类外资源的类必须定义拷贝控 ...

  7. c/c++ 拷贝控制 构造函数的问题

    拷贝控制 构造函数的问题 问题1:下面①处的代码注释掉后,就编译不过,为什么??? 问题2:但是把②处的也注释掉后,编译就过了,为什么??? 编译错误: 001.cpp: In copy constr ...

  8. c/c++ 拷贝控制 右值与const引用

    拷贝控制 右值与const引用 背景:当一个函数的返回值是自定义类型时,调用侧用什么类型接收?? 1,如果自定义类型的拷贝构造函数的参数用const修饰了:可以用下面的方式接收. Test t2 = ...

  9. C++ Primer 笔记——拷贝控制

    1.如果构造函数的第一个参数是自身类类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数.拷贝构造函数的第一个参数必须是引用类型(否则会无限循环的调用拷贝构造函数). 2.如果没有为一个类 ...

随机推荐

  1. 20针,14针,10针JTAG引脚对应关系

    J-Link是常用的调试工具,用于程序的调试和下载.常用的J-Link的的接口有很多种,常见的有20针,14针和10针. J-Link可以使用JTAG方式下载调试程序,也可以使用SWD方式.从引脚方面 ...

  2. TIOJ1208 第K大连续和

    第k大的题一般都有点麻烦 pbds库的tree,需要研究一下https://codeforces.com/blog/entry/11080find_by_order() and order_of_ke ...

  3. ERROR: HHH000091: Expected type: java.sql.Timestamp, actual value: java.lang.Integer

    在将MySql的数据对应到Java的实体类的时候, 遇到了错误 关键点: Hibernate从mysql数据库查出来的Timestamp类型的数据, 会被Hibernate(或者是数据库连接池Drui ...

  4. 用Jenkins构建项目实战

    登录Jenkins,新建任务 输入一个任务名称,选择一个项目类型 使用自定义工作空间:使该项目独立于系统的工作空间 自动从Git下载源码,点击添加可以增加凭证 日程表的参数: 第一个参数代表的是分钟 ...

  5. layui使用小记(持续更新)

    关于Select等Form表单元素,在使用的时候部分特性会失效 如select自带的Search功能: 其实在使用Form表单元素的时候,你如果需要layui自带的一些功能(搜索,验证等),请用< ...

  6. BERT模型介绍

    前不久,谷歌AI团队新发布的BERT模型,在NLP业内引起巨大反响,认为是NLP领域里程碑式的进步.BERT模型在机器阅读理解顶级水平测试SQuAD1.1中表现出惊人的成绩:全部两个衡量指标上全面超越 ...

  7. sorted倒序

    ''' sorted 可以排列list, reverse=True 可以倒序排列 ''' # # def list_Dict(x): # m = {} # for k,v in enumerate(x ...

  8. 【CodeForces 426】div1 B The Bakery

    Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredient ...

  9. hexo干货系列:(二)hexo主题下载及配置

    前言 上一篇文章介绍了hexo+gitHub简易搭建属于自己的个人独立博客,但是主题是默认的landscape,略显简单,今天的教程推荐Jacman主题. Jacman是一款为Hexo打造的一款扁平化 ...

  10. devstack脚本安装Openstack总结(转载)

    1:vmware 基本设置 我采用的vmware workstation 8.0的版本,其他版本应该都是没问题.我是把虚拟机放在NAT的网络. 虚拟机就单块网卡就可以. 如果你希望可以在dashboa ...