c++11 auto_ptr介绍
在代码里面看到了auto_ptr这个东西,正好以前一哥们曾经问过我这个问题..所以特意去搜了搜帖子,学习学习
http://www.cnblogs.com/gaoxianzhi/p/4451803.html
头文件 : #include <memory>
使用 : std::auto_ptr
作用 : 动态分配对象以及当对象不再需要时自动执行清理(意思就是你不用再去关心什么时候delete了也不用担心发生异常会有内存泄漏)
实现 : 在C++中, auto_ptr是一个类,它用来实现对动态分配对象的自动释放。
智能指针代码分析:
template<class T> //模板类
class auto_ptr
{
private:
T*ap; //int* ap; char* ap; father* ap; child* ap;
public:
//constructor & destructor-----------------------------------(1)
explicit auto_ptr(T*ptr=)throw():ap(ptr)//explicit->防止隐式转换(隐式转换只会在构造函数只有一个参数的时候发生)
{
} ~auto_ptr()throw() //直接删除ap.如果ap是null也没关系,c++不会认为错误
{
delete ap;
}
//Copy & assignment--------------------------------------------(2)
auto_ptr(auto_ptr& rhs)throw():ap(rhs.release()) //拷贝构造函数
{
} template<class Y> //模板拷贝构造函数-->重载的拷贝构造函数
auto_ptr(auto_ptr<Y>&rhs)throw():ap(rhs.release())
{
} auto_ptr& operator=(auto_ptr&rhs)throw() //重载的赋值操作符
{
reset(rhs.release());
return*this;
} template<class Y> //模板重载的赋值操作费
auto_ptr& operator=(auto_ptr<Y>&rhs)throw()
{
reset(rhs.release());
return*this;
} //Dereference----------------------------------------------------(3)
T& operator*()const throw() //重载* 注意返回的是类的引用
{
return *ap;
}
T* operator->()const throw() //重载->
{
return ap;
} //Helper functions------------------------------------------------(4)
//value access
T* get()const throw()
{
return ap;
} //release owner ship
T* release()throw() //此函数是在 返回临时对象???????????
{
T*tmp(ap); //调用构造函数tmp.ap 执行this->ap
ap=;
return tmp;
} //reset value
void reset(T*ptr=)throw()
{
if(ap!=ptr)
{
delete ap;
ap=ptr;
}
} //Special conversions-----------------------------------------------(5) //后面的真心看不懂啊
template<class Y>
struct auto_ptr_ref
{
Y* yp;
auto_ptr_ref(Y* rhs) : yp(rhs){}
};
auto_ptr(auto_ptr_ref<T>rhs)throw():ap(rhs.yp) //辅助的拷贝构造函数
{
} auto_ptr& operator=(auto_ptr_ref<T>rhs)throw()
{
reset(rhs.yp);
return*this;
} template<class Y>
operator auto_ptr_ref<Y>()throw()
{
return auto_ptr_ref<Y>(release());
} template<class Y>
operator auto_ptr<Y>()throw()
{
return auto_ptr<Y>(release());
}
};
|
1
2
|
int*p=new int(0);auto_ptr<int> ap(p); |
从此我们不必关心应该何时释放p,也不用担心发生异常会有内存泄漏。
注意事项:
1).auto_ptr析构的时候肯定会删除他所拥有的那个对象,所以我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。
int* p = new int();
auto_ptr<int> ap1(p);
auto_ptr<int> ap2(p); //错误,一个p给了两个智能指针
2).auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针
int* pa = new int[];
auto_ptr<int> ap(pa); //错误,在delete的时候只会删除数组的第一个元素,其他元素申请的空间不会被删除
3). 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型
4.)因为C++保证删除一个空指针是安全的, 所以我们没有必要把析构函数写成:
|
1
2
3
4
|
~auto_ptr()throw(){ if(ap)delete ap;} |
2 拷贝构造与赋值
与引用计数型智能指针不同的,auto_ptr要求其对“裸”指针的完全占有性。也就是说一个“裸”指针不能同时被两个以上的auto_ptr所拥有。那么,在拷贝构造或赋值操作时,我们必须作特殊的处理来保证这个特性。auto_ptr的做法是“所有权转移”,即拷贝或赋值的源对象将失去对“裸”指针的所有权,所以,与一般拷贝构造函数,赋值函数不同, auto_ptr的拷贝构造函数,赋值函数的参数为引用而不是常引用(const reference).当然,一个auto_ptr也不能同时拥有两个以上的“裸”指针,所以,拷贝或赋值的目标对象将先释放其原来所拥有的对象。
|
1
2
3
4
|
int*p=new int(0);auto_ptr<int>ap1(p);auto_ptr<int>ap2=ap1;cout<<*ap1;//错误,此时ap1只剩一个null指针在手了 |
|
1
2
3
4
5
6
7
8
|
void f(auto_ptr<int>ap){ cout<<*ap;}auto_ptr<int>ap1(new int(0));f(ap1);cout<<*ap1;//错误,经过f(ap1)函数调用,ap1已经不再拥有任何对象了。 |
|
1
2
|
class base{};class derived:public base{}; |
|
1
|
auto_ptr<base>apbase=auto_ptr<derived>(new derived); |
|
1
2
3
4
5
6
|
A a1;A a2(a1);A a3;a3=a1;//那么a2==a1,a3==a1 |
|
1
2
3
4
5
6
7
8
|
struct A{ void f();}auto_ptr<A>apa(new A);(*apa).f();apa->f(); |
|
1
|
auto_ptr<int>ap1=auto_ptr<int>(new int(0)); |
c++11 auto_ptr介绍的更多相关文章
- Go 1.11 Module 介绍
title: "Go 1.11 Module" date: 2018-10-26T23:50:56+08:00 draft: false --- Go 1.11 Module 介绍 ...
- C++11 auto_ptr 的问题
auto_ptr作为最早的智能指针,可以实现以RAII手法管理堆区对象,但它设计的本意只是简单的利用C++对于栈区对象的自动析构管理堆区对象, 并不像shared_ptr那样包含引用计数,可以在每次拷 ...
- C++11简要介绍
概述 C++1x (本教程中指 C++11/14, 甚至 C++17) 为传统 C++ 注入的大量特性使得整个 C++ 变得更加像一门现代化的语言.C++1x 不仅仅增强了 C++ 语言自身的可用性 ...
- 11. Grub 介绍
Grub 全称:Grand Unified Bootloader grub引导也分为两个阶段stage1阶段和stage2阶段(有些较新的grub又定义了stage1.5阶段). 一般配置文件:/bo ...
- python 1-1模块介绍和使用
1. 什么是模块 1.1 模块就是一系列功能的集合体 1.1.1 模块有三种来源 1.内置的模块 2.第三方的模块 3.自定义模块 1.1.2 模块的格式: 1.使用Python编写的.py文件 2. ...
- 【转】C++11 标准新特性: 右值引用与转移语义
VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...
- 你可能需要为你的 APP 适配 iOS 11
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/AZFrqL9dnlgA6Vt2sVhxIw 作者:s ...
- iOS 11 APP 设计中的几个 UI 设计细节
Apple 官网看了 iOS 11 的介绍,发现有不少的更新哦,比如控制中心.Siri.Live Photo 等等,总体来说都有很多不错的体验,不过本文不介绍功能,只说视觉界面. 在 iOS 11 的 ...
- PySpark SQL 相关知识介绍
title: PySpark SQL 相关知识介绍 summary: 关键词:大数据 Hadoop Hive Pig Kafka Spark PySpark SQL 集群管理器 PostgreSQL ...
随机推荐
- linux系统磁盘分区之parted
对于linux的分区通常可以使用fdisk命令工具和parted工具 对于分区表通常有MBR分区表和GPT分区表 对于磁盘大小小于2T的磁盘,我们可以使用fdisk和parted命令工具进行分区 对于 ...
- [HTTP] Origins, CROS, Preflight
Origins made up of three parts the data scheme, the hostname and the prot. It is important to know t ...
- android114 c转换成c++
##C向C++改造 . 把c文件后缀名换成cpp . Android.mk文件中的hello.c也要换成hello.cpp . c++的使用的环境变量结构体中,访问了c使用的结构体的函数指针,函数名全 ...
- 分享功能使用的UIPopoverController在iOS9 过期,替换为popoverPresentationController
记录一下 以备以后用到的时候拿出来看看.以前使用的: 1 if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom ...
- Cookie中用户登录信息登录验证
public class FormServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpSer ...
- Kafka 0.8: 多日志文件夹机制
kafka 0.7.2 中对log.dir的定义如下: log.dir none Specifies the root directory in which all log data is kept. ...
- KafkaSpout 浅析
最近在使用storm做一个实时计算的项目,Spout需要从 KAFKA 集群中读取数据,为了提高开发效率,直接使用了Storm提供的KAFKA插件.今天抽空看了一下KafkaSpout的源码,记录下心 ...
- javascript源码阅读推荐
作者:马 岩(Furzoom) (http://www.cnblogs.com/furzoom/)版权声明:本文的版权归作者与博客园共同所有.转载时请在明显地方注明本文的详细链接,未经作者同意请不要删 ...
- Scala应用函数
我们使用“_” 来代替单个的参数,实际上你也可以使用“_”来代替整个参数列表,比如说,你可以使用 print _ 来代替 println (_). someNumbers.foreach(printl ...
- Redis操作Set工具类封装,Java Redis Set命令封装
Redis操作Set工具类封装,Java Redis Set命令封装 >>>>>>>>>>>>>>>>& ...