1.scoped_ptr的实现原理及特性

特性:scoped_ptr和auto_ptr类似,但最大的区别就是不能转让管理权限,也就是说scoped_ptr禁止用户进行拷贝和赋值

实现原理:如何才能禁止一个类进行拷贝和复制呢?我们只需要将类的拷贝构造函数和赋值运算符重载的访问限定符设置为私有的可以

样例如下:

  1. class ScopedPtr{
  2. private:
  3. ScopedPtr(const ScopedPtr& sp);
  4. ScopedPtr& operator(const ScopedPtr& sp);
  5. };

scoped_ptr和auto_ptr类似,它包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确的删除,但是scoped_ptr的所有权更加严格,不能转让,一旦scoped_ptr获得了对象的管理权,你就无法再从它那里去回来

正如scoped_ptr(局部指针)名字的含义一样:这个指针只能在作用域里使用,不希望被转让

实现如下:

  1. template<class T>
  2. class scoped_ptr
  3. {
  4. private:
  5. T *px;
  6. scoped_ptr(scoped_ptr const &);
  7. scoped_ptr & operator=(scoped_ptr const &);
  8. public:
  9. explicit scoped_ptr(T *p = 0);
  10. ~scoped_ptr();
  11.  
  12. void reset(T *p = 0);
  13.  
  14. T & operator*()const;
  15. T * operator->()const;
  16. T * get()const;
  17.  
  18. operator unspecified-bool-type()const;
  19. void swap(scoped_ptr & b);
  20. };

分析:

scoped_ptr的构造函数接受一个类型为T*的指针p,创建出一个scoped_ptr对象,并在内部保存指针参数p,p必须是一个new表达式动态分配的结果或是一个空指针,当scoped_ptr的对象生命周期结束时,析构函数会使用delete操作自动销毁所保存的指针对象,从而正确的回收资源。

scoped_ptr同时把拷贝构造函数和赋值操作都声明为私有,禁止对scoped_ptr的复制操作,保证了被它管理的指针不能被转让所有权

成员函数reset的功能是重置scoped_ptr,它删除原来保存的指针,再保存新的指针值p,如果p是空指针,那么scopted_ptr将不能持有任何指针,一般情况下reset不应该配调用,因为它违背了scopted_ptr的本意---资源应该一直由scoped-ptr自己自动管理

实际上拥有权不可转移不够方便,swap成员函数可以交换两个scopted_ptr保存的原始指针,需要知道的是,scoped1.swap(scoped2) 只能用于它的定义所在的智能指针,而swap(scoped1,scoped2) 可以更广泛的用于很多指针类型,包括裸指针和第三方智能指针

scoped_ptr用operator*()和operator->()重载了引用操作符和箭头操作符,以模仿被代理的原始指针的行为,因此可以把scoped_ptr对象如同指针一样使用,如果scoped_ptr保存空指针,那么这两个操作都是未定义的

scoped_ptr不支持比较操作,不能在两个scoped_ptr之间,scoped_ptr和原始指针之间,scoped_ptr和空指针之间,进行相等或者不相等的比较操作,我们也无法为它编写额外的比较函数,因为其=和!=两个操作符都是私有的

2.scoped_ptr与auto_ptr的区别

1.scoped_ptr和auto_ptr的用法几乎一样,大多数情况下都可以与auto_ptr互换,它可以从一个auto_ptr获得指针的管理权(同时auto_ptr失去指针管理权)

2.scoped_ptr和auto_ptr一样不能用作容器的元素,但是原因不同,auto_ptr是因为它的转移语义,而scoped_ptr则是不支持拷贝和赋值,不符合容器对元素类型的要求

3.scoped_ptr和auto_ptr的根本区别在于所有权,auto_ptr被特意设计为所有权是可以被转移的,可以在函数之间传递,同一时刻只能有一个auto_ptr管理指针,而scoped_ptr把拷贝构造函数和赋值函数都声明为私有的,拒绝了指针所有权的转让,只有scoped_ptr自己能够管理指针,其他人都无权访问被管理的指针,从而保证了指针的绝对安全

4.如果代码企图从一个scoped_ptr构造或赋值另一个scoped_ptr,那么编译器会报错,阻止你这么做,从而保护你的代码,scoped_ptr更明确的表达了原始代码编写者的意图:只能在定义的作用域内使用,不可转让,这在代码后续的维持生命周期中很重要

样例如下:

  1. template<typename T>
  2. class ScopedPtr
  3. {
  4. public:
  5. ScopedPtr(T* ptr=NULL):_ptr(ptr){}
  6. ~ScopedPtr(){
  7. if(_ptr!=NULL)
  8. {
  9. delete _ptr;
  10. _ptr=NULL;
  11. }
  12. }
  13. private:
  14. ScopedPtr(const ScopedPtr &sp);
  15. ScopedPtr& operator=(const ScopedPtr &sp);
  16. private:
  17. T *_ptr;
  18. };
  19.  
  20. int main()
  21. {
  22. ScopedPtr<int> sp1(new int(10));
  23. ScopedPtr<int> sp2(new int(20));
  24.  
  25. //ScopedPtr<int> sp3(sp1); //编译错误 拷贝函数私有
  26. //sp1=sp2; //编译错误 =操作符私有
  27. }

由于boost::scoped_ptr独享指针所有权,当我们真的需要复制时,需求便满足不了,如此我们再引入一个智能指针boost::shared_ptr专门处理复制,参数传递的情况,下一节我们探讨boost::shared_ptr智能指针

C++ 智能指针 boost::scoped_ptr分析的更多相关文章

  1. [4] 智能指针boost::scoped_ptr

    [1]boost::scoped_ptr简介 boost::scoped_ptr属于boost库,定义在namespace boost中,包含头文件#include <boost/scoped_ ...

  2. [5] 智能指针boost::shared_ptr

    [1]boost::shared_ptr简介 boost::shared_ptr属于boost库,定义在namespace boost中,包含头文件#include<boost/shared_p ...

  3. [6] 智能指针boost::weak_ptr

    [1]boost::weak_ptr简介 boost::weak_ptr属于boost库,定义在namespace boost中,包含头文件 #include<boost/weak_ptr.hp ...

  4. 详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)

    一.boost 智能指针 智能指针是利用RAII(Resource Acquisition Is Initialization:资源获取即初始化)来管理资源.关于RAII的讨论可以参考前面的文章.在使 ...

  5. 【C/C++学院】0904-boost智能指针/boost多线程锁定/哈希库/正則表達式

    boost_array_bind_fun_ref Array.cpp #include<boost/array.hpp> #include <iostream> #includ ...

  6. 关于智能指针boost::shared_ptr

    boost库中的智能指针shared_ptr, 功能强大, 且开销小,故受到广大coder的欢迎. 但在实际的使用过程中,笔者也发现了一些不足. 1.定制的删除器 shared_ptr除了可以使用默认 ...

  7. C++ 智能指针 std::auto_ptr 分析

    背景介绍: RAll机制 定义一个类来封装资源的分配和释放,在构造函数中完成资源的分配和初始化,在析构函数中完成资源的清理,从而保证资源的正确初始化和清理 ps:智能指针就是RAll机制的一种应用,智 ...

  8. Qt智能指针简明说明

    下面的智能指针分别对应boost库,Qt库,c++11的智能指针 boost::scoped_ptr  QScopedPointer unique_ptr 在其生命期结束后会自动删除它所指的对象(确定 ...

  9. Boost中的智能指针(转)

    这篇文章主要介绍 boost中的智能指针的使用.(转自:http://www.cnblogs.com/sld666666/archive/2010/12/16/1908265.html) 内存管理是一 ...

随机推荐

  1. Modular Production Line (MCMF)

    Modular Production Line \[ Time Limit: 1000ms\quad Memory Limit: 65536kB \] 题意 给出 \(N\) 种零件,现在你可以用连续 ...

  2. 华三IRF配置

    配置步骤: IRF的配置步骤: 1.配置IRF域(域ID=10.成员ID.优先级) irf domain 10irf member 1 priority 10irf member 2 priority ...

  3. Python爬虫 | xpath的安装

    错误信息:程序包无效.详细信息:“Cannot load extension with file or directory name . Filenames starting with "& ...

  4. 6.学习springmvc的文件上传

    一.文件上传前提与原理分析 1.文件上传必要前提: 2.文件上传原理分析: 3.需要引入的jar包: 二.传统方式文件上传程序 1.pom.xml <dependency> <gro ...

  5. 鸿蒙OS与谷歌Fuchsia

    鸿蒙,意在“开天辟地”,它的征程是物联网.跨终端,是一款战略性产品.它真正对标的不是安卓,而是谷歌最新研发的操作系统Fuchsia. 根据Fuchsia中文社区的介绍,在安卓和 Chrome OS 两 ...

  6. December Challenge 2019 Division 1 题解

    传送门 当我打开比赛界面的时候所有题目都已经被一血了-- BINXOR 直接把异或之后二进制最多和最少能有多少个\(1\)算出来,在这个范围内枚举,组合数算一下就行了.注意\(1\)的个数是\(2\) ...

  7. 复旦高等代数I(19级)每周一题

    本学期的高等代数每周一题活动计划从第2教学周开始,到第15教学周结束,每周的周末公布一道思考题(共14道,思考题一般与下周授课内容密切相关),供大家思考和解答.每周一题将通过“高等代数官方博客”(以博 ...

  8. 洛谷P1084 疫情控制

    题目 细节比较多的二分+跟LCA倍增差不多的思想 首先有这样一个贪心思路,深度越低的检查点越好,而最长时间和深度具有单调性,即给定时间越长,每个军队能向更浅的地方放置检查点.因此可以考虑二分时间,然后 ...

  9. 【POJ3126】Prime Path

    本题传送门 本题知识点:宽度优先搜索 题意很简单.要找一个质数变到另一个质数的最少步数,两个质数都是4位数,变的时候只能变其中一位,变了的数也仍是质数. 思路也很简单,对每一位数进行修改,如果修改后的 ...

  10. Java 整数间的除法运算如何保留所有小数位?

      1.情景展示 double d = 1/10; System.out.println(d); 返回的结果居然是0.0!这是怎么回事儿? 2.原因分析 第一步:你会发现用运算结果也可以用int类型接 ...