必须要注意的 C++动态内存资源管理(二)——指针对象简单实现

四.拷贝类型的资源
        上节我们说过,对于图片类型的资源我们有时候往往采用拷贝(如果对于那种公共图片,可能采用唯一副本,提供地址使用)。这样情况,我们就需要在拷贝构造函数,以及拷贝赋值函数里面对源地址的内容(对象)进行拷贝。而在析构函数里面要释放自身所占有的资源。 template<typename T>
class res_ptr
{
public:
typedef res_ptr<T> _myType;
friend void swap(_myType& _Lhs, _myType& _Rhs){
std::swap(_Lhs.pointer, _Rhs.pointer); }
res_ptr(T* p = nullptr) :pointer(p){ }
res_ptr(const _myType& _Al) :pointer(new T(*_Al.pointer)){ }
~res_ptr(){ delete pointer; }
_myType& operator=(const _myType& _Rhs){
delete pointer; pointer = new _myType(*_Rhs.pointer); return *this;
}
T& operator*(){ return *pointer; }
private:
T* pointer;
};         对于这种类型的对象,当赋值的时候,就会产生多个资源副本。赋值之后,源对象和新对象就没有什么关系了。因为各自是操作的自身占有的资源副本。 五.控制权转移类型的资源
        如果了解过操作系统的,我们都知道有一类资源叫做临界资源,也就是只能同时被一个进程使用的资源。这里也是一样对于某些类如:设备(IO),文件的资源;这样的资源不能够进行拷贝,只能进行支配权的转移。 template<typename T>
class res_ptr
{
public:
typedef res_ptr<T> _myType;
friend void swap(_myType& _Lhs, _myType& _Rhs){
std::swap(_Lhs.pointer, _Rhs.pointer); }
res_ptr(T* p = nullptr) :pointer(p){ }
res_ptr( _myType& _Al) :pointer(_Al.pointer){
_Al.pointer = nullptr;
}
~res_ptr(){ delete pointer; }
_myType& operator=(_myType& _Rhs){
delete pointer; pointer = _Rhs.pointer;
_Rhs.pointer = nullptr; return *this;
}
T& operator*(){ return *pointer; }
private:
T* pointer;
};         对于这种类型的对象,当赋值的时候,就会产生多个资源副本。经过赋值,新对象获取资源之后,源对象就失去了对资源的支配权利。可能在这使用拷贝(赋值)这样的方式来表示支配权的转移不太合理,不过这里只是举个例子。 六.引用计数类型的资源
        还有一类资源,类似于数据库连接,网络sokets这样的可以共享的资源。从资源被创建开始可以被多个地方所”引用”,但是实际上的资源备份只有一个副本。当其中一个”引用”销毁了并一定会释放内存,只有当所有”引用”都失效(也就是这份资源没有使用者)的时候才会释放内存。在实现方法上,就需要多添加一个变量用来记录引用次数。 template<typename T>
class res_ptr
{
public:
typedef res_ptr<T> _myType;
friend void swap(res_ptr<T>& _Lhs, res_ptr<T>& _Rhs){
std::swap(_Lhs.use, _Rhs.use);
std::swap(_Lhs.pointer, _Rhs.pointer);
}
res_ptr(T* p = nullptr) :pointer(p), use(new std::size_t()){ }
res_ptr(const _myType& _Al) :pointer(_Al.pointer), use(_Al.use){ ++*use; } ~res_ptr(){
free();
}
_myType& operator=(const _myType& _Rhs){
++*_Rhs.use; free();
pointer = _Rhs.pointer; use = _Rhs.use;
return *this;
}
T& operator*(){ return *pointer; }
std::size_t user(){ return *use; }
private:
void free(){ if (--*use == ){ delete pointer; delete use; printf("析构\n"); } }
T* pointer;
std::size_t *use;
};         通过添加引用次数来判断资源的最后一个使用者,因为在使用者创建和销毁的时候要对该资源的所有使用者的计数器都要更新,所以计数器我们要使用指针,这样大家记录地址,一个更新大家都更新了。提供了user()方法可以查看该资源有多少使用者。 下一节我们来介绍C++11中的智能指针 :shared_ptr , unique_ptr , weap_ptr

必须要注意的 C++ 动态内存资源管理(二)——指针对象简单实现的更多相关文章

  1. 必须要注意的 C++ 动态内存资源管理(六)——vector的简单实现

    必须要注意的 C++ 动态内存资源管理(六)——vector的简单实现 十六.myVector分析         我们知道,vector类将其元素存放在连续的内存中.为了获得可接受的性能,vetor ...

  2. 必须要注意的 C++ 动态内存资源管理(一)——视资源为对象

    必须要注意的 C++ 动态内存资源管理(一)——视资源为对象 一.前言         所谓资源就是,一旦你用了它,将来必须还给系统.如果不这样,糟糕的事情就会发生.C++ 程序中最常见使用的资源就是 ...

  3. 必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱

    必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱 十三.小心使用智能指针.         在前面几节已经很详细了介绍了智能指针适用方式.看起来,似乎智能指针很强大,能够很方便很安全的管理 ...

  4. 【足迹C++primer】39、动态内存与智能指针(3)

    动态内存与智能指针(3) /** * 功能:动态内存与智能指针 * 时间:2014年7月8日15:33:58 * 作者:cutter_point */ #include<iostream> ...

  5. 12.动态内存和智能指针、 直接管理内存、shared_ptr和new结合使用

    12.动态内存和智能指针 1.智能指针分为两种shared_ptr和unique_ptr,后者独占所指向的对象.智能指针也是模板,使用时要用尖括号指明指向的类型.类似emplace成员,make_sh ...

  6. 【C++】动态内存与智能指针

    C++常见的内存分配方式有三种: 从静态存储区分配,这里主要是存储局部static对象,类的static成员以及定义在函数之外的变量: 从栈内存分配,这里主要是存储函数内的非static对象: 从堆内 ...

  7. C++相关:动态内存和智能指针

    前言 在C++中,动态内存的管理是通过运算符new和delete来完成的.但使用动态内存很容易出现问题,因为确保在正确的时间释放内存是及其困难的.有时候我们会忘记内存的的释放,这种情况下就会产生内存泄 ...

  8. c++学习笔记—动态内存与智能指针浅析

    我们的程序使用内存包含以下几种: 静态内存用来保存局部static对象.类static数据成员以及定义在任何函数之外的变量,在使用之前分配,在程序结束时销毁. 栈内存用来保存定义在函数内部的非stat ...

  9. C++——动态内存分配2-创建对象数组

    //创建对象数组 #include<iostream> using namespace std; class Point { public:        Point()       {  ...

随机推荐

  1. H3C IEEE 802.11无线局域网工作组

  2. Pthon魔术方法(Magic Methods)-容器相关方法

    Pthon魔术方法(Magic Methods)-容器相关方法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.容器相关方法汇总 __len__: 内建函数len(),返回对象的 ...

  3. Unity进阶:行为树 01

    版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...

  4. 状压dp之位运算

    ## 一.知识 1.我们知道计算机中数据由二进制数存储,一个二进制数的一位就是计算机中数据的最小单位bit,我们有一种运算符可直接对二进制数进行位运算,所以它的速度很快. 2.C++中的位运算符有6种 ...

  5. danci3

    permit 英 [pə'mɪt] 美 [pɚ'mɪt] vi. 许可:允许 vt. 许可:允许 n. 许可证,执照 encapsulate 英 [ɪn'kæpsjʊleɪt; en-] 美 [ɪn' ...

  6. MERGE引擎 分表后 快速查询所有数据

    MERGE存储引擎把一组MyISAM数据表当做一个逻辑单元来对待,让我们可以同时对他们进行查询.构成一个MERGE数据表结构的各成员MyISAM数据表必须具有完全一样的结构.每一个成员数据表的数据列必 ...

  7. C++ EH Exception(0xe06d7363)---捕获过程

    书接上文<C++ EH Exception(0xe06d7363)----抛出过程>,下面我们讲下,VC++是如何catch到异常且处理的. 我们知道,在VC++里,C++异常实现的底层机 ...

  8. 权限管理(chown、chgrp、umask)

    对于文件或目录的权限的修改,只能管理员和文件的所有者拥有此权限,但是对于文件或目录的的所有者的更改,只有管理员拥有此权限(虽然普通用户创建的文件或目录,用户也不能修改文件或目录的所有者). 1.cho ...

  9. amundsen 来自lyft 的开源数据发现平台

    amundsen 是来自lyft 开源的元数据管理.数据发现平台,功能点很全,有一个比较全的前端.后端以及 数据处理框架 参考架构图 说明 从官方介绍以及github代码仓库可以看出还是比较全的整体解 ...

  10. 4-微信小程序开发(小程序默认页面函数说明)

    https://www.cnblogs.com/yangfengwu/p/11601299.html 源码下载链接: 或者 首先说一下,怎么让自己的一个项目更改名字成为一个新的项目 然后用软件导入项目 ...