拷贝控制和资源管理

13.2.1行为像值的类

*定义一个拷贝构造函数,完成string的拷贝,而不是拷贝指针
*定义一个析构函数来释放string
*定义一个拷贝赋值运算符来释放对象当前的string,并从右侧运算对象拷贝string
class   HasPtr
{
public:HasPtr(const string &s=string()):ps(new string(s)), i(0){}//对ps指向的string,每个HasPtr对象都有自己的拷贝HasPtr(const HasPtr &p):ps(new string(*p.ps)), i(p.i) {}HasPtr & operator=(const HasPtr &);~HasPtr() {delete ps;}private:string *ps;int     i;
};

类值拷贝赋值运算符

HasPtr& HasPtr::operator=(const HasPtr &rhs)
{auto newp=new string(*rhs.ps);      //拷贝底层stringdelete ps;          //释放旧内存ps=newp;            //从右侧运算对象拷贝数据到本对象i=rhs.i;return *this;       //返回本对象
}

这里有一个错误的示范!!

HasPtr& HasPtr::operator=(const HasPtr &rhs)
{delete ps;      //释放对象指向string//如果rhs和*this是同一个人对象,我们就将从已释放的内存中拷贝数据!ps=new string(*(rhs.ps));i=rhs.i;return *this;
}

看出来了么,这里new string(*(rhs.ps))里面的ps是已经释放了的,也就是把释放过的内存拿来赋值,显然是未定义的

13.2.2定义行为像指针的类

令一个类展现类似指针的行为的最好的方法是使用shared_ptr来管理类中的资源
但是,有时候我们希望直接管理资源。在这种情况下,使用引用计数

引用计数

void fun1()
{HasPtr p1("Hiya!");HasPtr p2(p1);      //p1和p2指向相同的stringHasPtr p3(p1);      //p1、p2、p3都指向相同的string
}

定义一个使用引用计数的类

<pre name="code" class="cpp">class HasPtr2
{
public://构造函数分配新的string和新的计数器,将计数器置为1HasPtr2(const string &s):ps2(new string(s)), i2(0), use(new size_t(1)){}//拷贝构造函数拷贝所有三个数据成员,并递增计数器HasPtr2(const HasPtr2 &p):ps2(p.ps2), i2(p.i2), use(p.use) {++*use;}HasPtr2 & operator=(const HasPtr2 &);~HasPtr2();private:string *ps2;int i2;size_t *use;    //记录有多少个对象共享*ps的成员
};HasPtr2::~HasPtr2()
{if(--*use==0)   //调用析构函数就要--{//如果引用计数变为0delete ps2;  //释放string内存delete use; //释放计数器内存}
}HasPtr2 & HasPtr2::operator=(const HasPtr2 &rhs)
{++*rhs.use;     //拷贝一个,那就递增一个计数if(--*use == 0)     //递减本对象的引用计数{delete ps2;     //如果没有其他用户了delete use;     //释放分配的成员}/*上面这个if应该如何去看呢?rhs拷贝给一个对象的时候,指向rhs的对象就会多一个所以++然后拷贝的对象,得到新值就会把原来的值去掉所以会--然后看是不是最后一个是的话直接销毁,不是那就不管--就可以了*/ps2=rhs.ps2;i2=rhs.i2;use=rhs.use;return *this;       //返回本对象
}

全代码!!!

/**
* 功能:拷贝控制和资源管理
* 时间:2014年7月13日08:54:26
* 作者:cutter_point
*/#include<iostream>
#include<string>using namespace std;/**************************************
13.2.1行为像值的类
**************************************//*
*定义一个拷贝构造函数,完成string的拷贝,而不是拷贝指针
*定义一个析构函数来释放string
*定义一个拷贝赋值运算符来释放对象当前的string,并从右侧运算对象拷贝string
*/
class   HasPtr
{
public:HasPtr(const string &s=string()):ps(new string(s)), i(0){}//对ps指向的string,每个HasPtr对象都有自己的拷贝HasPtr(const HasPtr &p):ps(new string(*p.ps)), i(p.i) {}HasPtr & operator=(const HasPtr &);~HasPtr() {delete ps;}private:string *ps;int     i;
};/**
类值拷贝赋值运算符
*/
HasPtr& HasPtr::operator=(const HasPtr &rhs)
{auto newp=new string(*rhs.ps);      //拷贝底层stringdelete ps;          //释放旧内存ps=newp;            //从右侧运算对象拷贝数据到本对象i=rhs.i;return *this;       //返回本对象
}//这里有一个错误的示范!!
/*
HasPtr& HasPtr::operator=(const HasPtr &rhs)
{delete ps;      //释放对象指向string//如果rhs和*this是同一个人对象,我们就将从已释放的内存中拷贝数据!ps=new string(*(rhs.ps));i=rhs.i;return *this;
}
*/
//看出来了么,这里new string(*(rhs.ps))里面的ps是已经释放了的,也就是把释放过的内存拿来赋值,显然是未定义的/**************************************
13.2.2定义行为像指针的类
**************************************//*
令一个类展现类似指针的行为的最好的方法是使用shared_ptr来管理类中的资源
但是,有时候我们希望直接管理资源。在这种情况下,使用引用计数
*//**
引用计数
*/void fun1()
{HasPtr p1("Hiya!");HasPtr p2(p1);      //p1和p2指向相同的stringHasPtr p3(p1);      //p1、p2、p3都指向相同的string
}/**
定义一个使用引用计数的类
*/class HasPtr2
{
public://构造函数分配新的string和新的计数器,将计数器置为1HasPtr2(const string &s):ps2(new string(s)), i2(0), use(new size_t(1)){}//拷贝构造函数拷贝所有三个数据成员,并递增计数器HasPtr2(const HasPtr2 &p):ps2(p.ps2), i2(p.i2), use(p.use) {++*use;}HasPtr2 & operator=(const HasPtr2 &);~HasPtr2();private:string *ps2;int i2;size_t *use;    //记录有多少个对象共享*ps的成员
};HasPtr2::~HasPtr2()
{if(--*use==0)   //调用析构函数就要--{//如果引用计数变为0delete ps2;  //释放string内存delete use; //释放计数器内存}
}HasPtr2 & HasPtr2::operator=(const HasPtr2 &rhs)
{++*rhs.use;     //拷贝一个,那就递增一个计数if(--*use == 0)     //递减本对象的引用计数{delete ps2;     //如果没有其他用户了delete use;     //释放分配的成员}/*上面这个if应该如何去看呢?rhs拷贝给一个对象的时候,指向rhs的对象就会多一个所以++然后拷贝的对象,得到新值就会把原来的值去掉所以会--然后看是不是最后一个是的话直接销毁,不是那就不管--就可以了*/ps2=rhs.ps2;i2=rhs.i2;use=rhs.use;return *this;       //返回本对象
}int main()
{return 0;
}

PS:这期还是没有效果图,因为我都没有在主函数中加相应的函数,不过无所谓啦,代码是没错的,能通过编译,至少没有语法错误,还有就是定义类,应该不会出现逻辑错误吧!!!嘿嘿,其实这节应该可以9点左右就发出来的,但是你能想象我9点左右出去打印照片吗????

打印 苍老师的照片!!!苍老师!!!没错就是苍井空。。。。打印室的老板盯着我看了半天,这家伙干嘛。。。。

【足迹C++primer】43、拷贝控制和资源管理相关推荐

  1. 拷贝控制——拷贝控制和资源管理,交换操作,对象移动

    一.拷贝控制和资源管理 通常,管理类外资源的类必须定义拷贝控制成员,这种类需要通过析构函数来释放对象所分配的资源. 为了定义这些成员,我们首先必须确定此类型对象的拷贝语义.一般来说,有两种选择:可以定 ...

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

    CHAPTER13-拷贝控制(C++ Primer笔记) 13.1 拷贝.赋值与销毁 13.1.1 拷贝构造函数 13.1.2 拷贝赋值运算符 13.1.3 析构函数 13.1.4 三/五法则 13. ...

  3. 【C++】拷贝控制与资源管理

    1. 拷贝控制与资源管理 管理类外资源的类必须定义拷贝控制成员.如P447中所见,这种类需要通过析构函数来释放对象所分配的资源.一旦一个类需要析构函数,那么几乎可确定它也需要一个拷贝构造函数和一个拷贝 ...

  4. 37.拷贝控制和资源管理

    类中只要有一个成员不可能拷贝.赋值.析构的话,类的合成拷贝控制成员就被定义为delete 在新标准发布之前,要想阻止拷贝,类将拷贝构造函数和拷贝赋值运算符声明为private,只是声明,没有给出定义. ...

  5. C++ primer 第13章 拷贝控制

    文章目录 前言 拷贝.赋值与销毁 拷贝构造函数 合成拷贝构造函数 拷贝初始化和直接初始化 拷贝初始化的发生: 参数和返回值 拷贝初始化的限制 拷贝赋值运算符 重载赋值运算符 合成拷贝赋值运算符 析构函 ...

  6. C++ primer 第13章 拷贝控制

    文章目录 前言 拷贝.赋值与销毁 拷贝构造函数 合成拷贝构造函数 拷贝初始化和直接初始化 拷贝初始化的发生: 参数和返回值 拷贝初始化的限制 拷贝赋值运算符 重载赋值运算符 合成拷贝赋值运算符 析构函 ...

  7. C++ Primer 第十三章 拷贝控制

    当定义一个类时,我们显式或隐式指定在此类型的对象执行拷贝,移动,赋值,销毁时做什么,通过拷贝构造函数,拷贝赋值运算符,移动构造函数,移动赋值运算符和析构函数. 拷贝赋值与销毁 如果构造函数的第一个参数 ...

  8. C++primer学习(13.拷贝控制)

    拷贝控制 每个类都定义了一个新类型和在此类型对象上可执行的操作.类可以定义构造函数,用来控制在创建此类型对象时做什么. 当定义一个类时,我们显式或隐式地指定在此类型的对象拷贝.移动.赋值和销毁时做什么 ...

  9. 【C++】C++的拷贝控制

    目录结构: contents structure [-] 拷贝.赋值与销毁 拷贝构造函数 拷贝初始化 参数和返回值 拷贝赋值运算符 析构函数 三五法则 拷贝控制和资源管理 交换操作 对象移动 右值引用 ...

最新文章

  1. SQL Server 中各个系统表的作用
  2. 跳石头 NOIP2015 提高组 Day2 T1
  3. 算法笔记_188:历届试题 危险系数(Java)
  4. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十:SDRAM模块③ — 页读写 α...
  5. Python-语句执行
  6. AD中批量增加带密码用户
  7. python中的文件操作
  8. jenkins部署三种构建方式的详细步骤
  9. Oracle 获取每月最后一天的函数
  10. RS232与RS485
  11. 如何删除github上的文件
  12. keras读取训练好的模型参数并把参数赋值给其它模型
  13. 自动按键 回车 变成_【按键大扫荡】驾驶员的“眼”
  14. 信号在网线和集线器中的传输(《网络是怎样连接的》).md
  15. 大二 数据结构 期末复习题(仅供参考)
  16. 西门子em235模块的功能_与其研究人工智能不如研究可编程控制器之德国西门子PLCS7200...
  17. resin log日志
  18. 评论与回复数据表设计
  19. 【最全】you-get和youtube-dl的安装和使用
  20. 笔记——51控制DS18B20温度控制篇章之终章温度报警

热门文章

  1. 以太坊的POS共识机制(二)理解 Serenity :Casper
  2. Python-字符串
  3. 浏览器显示“您与此网站之间建立的连接不安全”的解决方案
  4. 史上最全APP推广渠道
  5. ESP8266 驱动1.3寸SH1106 OLED屏幕显示库
  6. 全能修图工具Pixelmator Pro Mac
  7. 陶森大学计算机专业收入水平,2019PayScale计算机专业本科薪水排行
  8. 速度与压缩比如何兼得?压缩算法在构建部署中的优化
  9. 上海镇保城保四金比例
  10. 国开电大 公共关系学 形考任务答案 实训项目