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 ...
随机推荐
- wpf 透明窗体中使用webbrowser
wpf ,PNG图形半透明窗体 ,使用webbrowser控件 附件:http://files.cnblogs.com/xe2011/WpfApplication1_webbrowser_tran ...
- C# #define
https://msdn.microsoft.com/library/yt3yck0x.aspx 使用 #define 定义符号.当您将符号用作传递给 #if 指令的表达式时,此表达式的计算结果为 t ...
- Match+Faq
假如在GameLayer.h中有Card类型的变量,那么在Card.h文件中,不要有GameLayer.h的导入.这样子会导致编译器找不到对Card类型的定义而导致报错.但是,在Card.cpp中可以 ...
- Linux运维工程师成长必经之路
本路线图是从0基础开始,全方位由浅入深,按照多年Linux培训经验和优秀教学方法制定的学习思路和学习方法,路线图包括初级入门.中级进阶.高级提升和资深冲刺四个阶段,每阶段对应着不同优秀的课程和学习方法 ...
- Android开发之线程池使用总结
线程池算是Android开发中非常常用的一个东西了,只要涉及到线程的地方,大多数情况下都会涉及到线程池.Android开发中线程池的使用和Java中线程池的使用基本一致.那么今天我想来总结一下Andr ...
- Python之路【第二十二篇】:Django之Model操作
Django之Model操作 一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bi ...
- php 中json_decode()和json_encode()的使用方法
1.json_decode() json_decode (PHP 5 >= 5.2.0, PECL json >= 1.2.0) json_decode — 对 JSON 格式的字符串进行 ...
- hbuilder用自己的服务
2016-03-10 以后写测试demo用Sublime3 http://docs.emmet.io/cheat-sheet/ 更多炫酷信息和emmet语法请参见: 视频demo 语法文档 2016- ...
- nvidia安装与卸载方式
第1种方法:.最好的方式不是手动安装官方驱动(手动安装官方驱动无法使用gpu,而且无法启用3d,同时无法生效,所以最好采用此种方法),而是使用bumblebee-nvidia安装,不过要先添加x-sw ...
- ios专题 -block用法
what is block Blocks are a language-level feature added to C, Objective-C and C++, which allow you t ...