智能指针之auto_ptr和scoped_ptr
部分参考地址https://blog.csdn.net/yanglingwell/article/details/56011576
auto_ptr是c++标准库里的智能指针,但是具有以下几个明显的缺陷,使用时要注意
1.就是所谓的控制权转移,下面是模拟代码
auto_Ptr(auto_Ptr<T>&ap)
{
_ptr = new T; //先分配空间
_ptr = ap._ptr; //再资源转移
ap._ptr = NULL; //将原来的指针置空
}
在赋值运算符重载和拷贝构造函数中将资源转移,来的指针被赋空,要是再进行一些使用的语句那么程序会崩溃
2.不能管理数组
~auto_ptr() _NOEXCEPT
{ // destroy the object
delete _Myptr;
}
void reset(_Ty *_Ptr = 0)
{ // destroy designated object and store new pointer
if (_Ptr != _Myptr)
delete _Myptr;
_Myptr = _Ptr;
}
这是auto_ptr内部析构和重置的代码,如果是数组需要delete[],所以不能完全释放数组的内存
另外分析一下auto_ptr的几个源代码
当我执行下面这句代码时
std::auto_ptr<int>b(auto_ptr<int>(new(int)));
执行顺序如下
explicit auto_ptr(_Ty *_Ptr = ) _THROW0()
: _Myptr(_Ptr)
{ // construct from object pointer
}
//这个应该起隐式转换的作用
template<class _Other>
operator auto_ptr_ref<_Other>() _THROW0()
{ // convert to compatible auto_ptr_ref
_Other *_Cvtptr = _Myptr; // test implicit conversion
auto_ptr_ref<_Other> _Ans(_Cvtptr);
_Myptr = ; // pass ownership to auto_ptr_ref
return (_Ans);
} auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0()
{ // construct by assuming pointer from _Right auto_ptr_ref
_Ty *_Ptr = _Right._Ref;
_Right._Ref = ; // release old
_Myptr = _Ptr; // reset this
} ~auto_ptr() _NOEXCEPT
{ // destroy the object
delete _Myptr;
}
对于auto_ptr_ref是什么东西,下面是一段解释(我是没太懂为什么会调用operator auto_ptr_ref<_Other>())
Q: what is auto_ptr_ref, what it achieves and how it achieves it ?
A: It is rather confusing. Basically, auto_ptr_ref exists because the auto_ptr copy constructor isn’t really a copy constructor in the standard sense of the word.
Copy constructors typically have a signature that looks like this:
X(const X &b);
The auto_ptr copy constructor has a signature that looks like this:
X(X &b)
This is because auto_ptr needs to modify the object being copied from in order to set its pointer to 0 to facilitate the ownership semantics of auto_ptr.
Sometimes, temporaries cannot match a copy constructor that doesn’t declare its argument const. This is where auto_ptr_ref comes in. The compiler won’t be able to call the non-const version of the copy constructor, but it can call the conversion operator. The conversion operator creates an auto_ptr_ref object that’s just sort of a temporary holder for the pointer. The auto_ptr constructor or operator = is called with the auto_ptr_ref argument.
If you notice, the conversion operator in auto_ptr that automatically converts to an auto_ptr_ref does a release on the source auto_ptr, just like the copy constructor does.
It’s kind of a weird little dance that happens behind the scenes because auto_ptr modifies the thing being copied from.
简单地总结: auto_ptr_ref 主要解决用右值来构造 auto_ptr 的情况。 因为, auto_ptr(auto_ptr& r) 构造函数只能以左值引用做参数。当右值来构造 auto_ptr_ref 的时候,实际上实现过程如下(这其实是移动语义的早期实现版本):
scoped_ptr类似于auto_ptr但是弥补了它的部分缺陷,scoped_ptr的所有权更加严格,不能转让,一旦scoped_pstr获取了对象的管理权,你就无法再从它那里取回来。
代码实现如下:
template<class T>
class scoped_ptr{
private:
T *px;
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
public:
explicit scoped_ptr(T *p = 0);
~scoped_ptr();
void reset(T *p = 0);
T & operator*()const;
T * operator->()const;
T * get()const;
operator unspecified-bool-type()const;
void swap(scoped_ptr & b);
};
可见,scoped_str的构造函数接受一个类型为T*的指针p,创建出一个scoped_ptr对象,并在内部保存指针参数p。p必须是一个new表达式动态分配的结果,或者是一个空指针(0)。当scoped_ptr对象的生命周期结束时,析构函数~scoped_ptr()会使用delete操作自动销毁所保存的指针对象,从而正确的回收资源。
scoped_ptr同时把拷贝构造函数和赋值操作都声明为私有的,禁止对智能指针的复制操作,保证了被它管理的指针不能被转让所有权。
最后加一点
!智能指针都应避免的一点:
string vacation("I wandered lonely as a cloud.");
shared_ptr<string> pvac(&vacation); // No
pvac过期时,程序将把delete运算符用于非堆内存,这是错误的。
智能指针之auto_ptr和scoped_ptr的更多相关文章
- 【C++深入浅出】智能指针之auto_ptr学习
起: C++98标准加入auto_ptr,即智能指针,C++11加入shared_ptr和weak_ptr两种智能指针,先从auto_ptr的定义学习一下auto_ptr的用法. template& ...
- [3] 智能指针std::auto_ptr
[1]std::auto_ptr 对于编译器来说,智能指针实质是一个栈对象,而并非指针类型. 智能指针通过构造函数获取堆内存的管理所有权,而在其生命期结束时,再通过析构函数释放由它所管理的堆内存. 所 ...
- 智能指针之 auto_ptr
C++的auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理,该智能指针在C++11中已经被弃用,转而由unique_ptr替代, 那这次使用和实现,就具体讲一下auto_pt ...
- C++ 智能指针 std::auto_ptr 分析
背景介绍: RAll机制 定义一个类来封装资源的分配和释放,在构造函数中完成资源的分配和初始化,在析构函数中完成资源的清理,从而保证资源的正确初始化和清理 ps:智能指针就是RAll机制的一种应用,智 ...
- 智能指针shared_ptr, auto_ptr, scoped_ptr, weak_ptr总结
看这里: http://blog.csdn.net/lollipop_jin/article/details/8499530 shared_ptr可以多线程同时读,但是涉及到写,需要加锁. share ...
- auto_ptr,shared_ptr 智能指针的使用
Q: 那个auto_ptr是什么东东啊?为什么没有auto_array?A: 哦,auto_ptr是一个很简单的资源封装类,是在<memory>头文件中定义的.它使用“资源分配即初始化”技 ...
- c++智能指针(unique_ptr 、shared_ptr、weak_ptr、auto_ptr)
一.前序 什么是智能指针? ——是一个类,用来存储指针(指向动态分配对象也就是堆中对象的的指针). c++的内存管理是让很多人头疼的事,当我们写一个new语句时,一般就会立即把delete语句直接也写 ...
- C++ 智能指针Auto_PTR 分析
C++的动态内存的分配与释放是个挺折磨人的事情,尤其异常分支复杂时(比如一堆try catch中,各catch里需要做delete 掉相关的堆上分配的内存),极有可能产生内存泄露的情况.C++中提供了 ...
- 32.智能指针auto_ptr
#include <iostream> #include <memory> #include <string> #include <vector> us ...
随机推荐
- Maven的目录结构和常用命令
一.Maven项目的目录结构 1.顶级目录结构 src:该目录主要存放的是项目的源代码文件. target:该目录是项目编译后产生的一个目录,主要存放的是编译后的.class文件. pom.xm ...
- uni-app 页面配置和跳转(一)转
今天看Dcloud官网更新了个uni-app,据说一套代码三端发布(Android,iOS,微信小程序),果断一试. uni.navigateTo(OBJECT) 保留当前页面,跳转到应用内的某个页面 ...
- 解决WORD2013输入时光标老跳的问题
Word2013有一个非常影响使用的bug.就是在编辑文档时,光标会乱跑,影响输入.微软给出了一个kb2863845 160多MB的补丁包,安装完成后就可以解决这个问题. 补丁下载链接: 链接:ht ...
- 2.VS2012为创建的类添加注释的模板
在项目中给类添加注释的优点: 1.方便查看这个类是为了那些功能 2.是成员小组中的谁负责编写的 根据自己的vs的安装路径找到类模板的位置:D:\Program Files (x86)\Microsof ...
- 利用canvas制作图片(可缩放和平移)+相框+文字
前言: 公司一个售前问我能不能用H5做一个手机拍照,给相片添加相框和添加文字上传到服务器的功能,我当时一琢磨觉得可行,就利用空余时间做了一个demo,去掉了拍照和上传,如果以后有机会,会给补上,当然对 ...
- 解决github无法访问的问题
gitbub是外网,经常会遇到访问不了的问题,并且有时能访问也网速好慢. 解决这个问题的方法是 更改hosts文件,地址: C:\Windows\System32\Drivers\etc 我在hos ...
- java泛型使用
泛型的解释 现在感觉泛型是一个值得学习的地方,就抽出时间来学习和总结一下泛型的使用. Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允 ...
- jquery echarts 饼状图
var myChart = echarts.init(document.getElementById('myChart')); option = { title : { text: '某站点用户访问来 ...
- 插入排序——Python实现
一.排序思想 排序思想参见:https://www.cnblogs.com/luomeng/p/10583124.html 二.python实现 def InsertSort(arrs): " ...
- JavaScript之parseInt()数值转换常被忽略的问题
使用parseInt()你可以从字符串中获取数值,该方法接受另一个基数参数,这经常省略,但不应该.当字符串以”0″开头的时候就有可能会出问题,例如,部分时间进入表单域,在ECMAScript 3中,开 ...