关于智能指针auto_ptr
智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个
感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解。
本篇主要介绍auto_ptr
其特点如下:
1.首先auto_ptr智能指针是个封装好的类;
2.是采用栈上的指针去管理堆上的内容,所以auto_ptr所管理的对象必须是new出来的,也不能是malloc出来的,
原因:在auto_ptr的实现机制中,采用的是delete 掉一个指针,该delete一方面是调用了指针所指对象的析构函数(这也是为什么采用智能指针,new了一个对象,但是不用delete的原因),另一方面释放了堆空间的内存;
3.一块堆上的内存不能被两个智能指针同时指向(这个就是所有权和管理权的问题),想想也是,如果两个智能指针同时指向的话,每个智能指针对象析构的时候,都会调用一次delete,导致堆空间内存被释放两次,然而这是不被允许的。
4.aut0_ptr不能管理数组,因为析构调用的是delete,如果管理数组的话,需要调用delete[];
相比于普通指针的额优点就是:
普通指针在new 和delete之间发生异常,并且异常不能被捕获的话,就不会执行delete,那么这片内存就不能被回收。
但是auto_ptr就不会存在这样的问题。
其具体实现代码如下:应该是别人写的啊,感觉写的很不错啊,基本实现了auto_ptr的所有功能,而且容易读懂!
//auto_ptr.h #ifndef AUTO_PTR_H
#define AUTO_PTR_H template<typename T>
class auto_ptr
{
public :
//使用explicit关键字避免隐式转换
explicit auto_ptr(T* p=); ~auto_ptr(); //使用另一个类型兼容的auto_ptr来初始化一个新的auto_ptr
template<typename U>
auto_ptr(auto_ptr<U>& rhs); template<typename U>
auto_ptr<T>& operator=(auto_ptr<U>& rhs); T& operator*() const;
T* operator->() const; //返回原始对象的指针
T* get() const;
//放弃指针的所有权
T* release();
//删除原有指针并获得指针的p的所有权
void reset(T* p=); private:
T* pointee; }; template<typename T>
auto_ptr<T>::auto_ptr(T* p)
:pointee(p)
{} template<typename T>
template<typename U>
auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
:pointee(rhs.release())
{} template<typename T>
auto_ptr<T>::~auto_ptr()
{
delete pointee;
} template<typename T>
template<typename U>
auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
{
if(this!=&rhs)
reset(rhs.release());
return *this;
} template<typename T>
T& auto_ptr<T>::operator*() const
{
return *pointee;
} template<typename T>
T* auto_ptr<T>::operator->() const
{
return pointee;
} template<typename T>
T* auto_ptr<T>::get() const
{
return pointee;
} template<typename T>
T* auto_ptr<T>::release()
{
T* oldpointee=pointee;
pointee=;
return oldpointee;
} template<typename T>
void auto_ptr<T>::reset(T* p)
{
if(pointee!=p)
{
delete pointee;
pointee=p;
}
} #endif
//Item.h
#ifndef ITEM_H
#define ITEM_H class Item
{
public:
Item(void);
~Item(void); void PrintContent() const;
}; #endif //Item.cpp
using std::cout;
using std::endl; Item::Item(void)
{
cout<<"constructor"<<endl;
} Item::~Item(void)
{
cout<<"Destorying....."<<endl;
} void Item::PrintContent() const
{
cout<<"Here is the content"<<endl;
}
#include <iostream>
#include "auto_ptr.h"
#include "Item.h" using std::cout; int main()
{ auto_ptr<Item> itemPtr(new Item);
itemPtr->PrintContent();
auto_ptr<Item> itemPtr2(itemPtr);
itemPtr2->PrintContent();
return ;
}
关于智能指针auto_ptr的更多相关文章
- C++智能指针(auto_ptr)详解
智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...
- 自己动手实现智能指针auto_ptr
面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍. auto_ptr归根到底是一个模版类,那么这个类要实现哪 ...
- C++ 智能指针auto_ptr
template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...
- C++中的智能指针(auto_ptr)
实际上auto_ptr 仅仅是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势.使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是全然完美的. 本 ...
- 【C++】智能指针auto_ptr简单的实现
//[C++]智能指针auto_ptr简单的实现 #include <iostream> using namespace std; template <class _Ty> c ...
- 智能指针auto_ptr & shared_ptr
转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...
- C++智能指针 auto_ptr
C++智能指针 auto_ptr auto_ptr 是一个轻量级的智能指针, 定义于 memory (非memory.h)中, 命名空间为 std. auto_ptr 适合用来管理生命周期比较短或者不 ...
- C++智能指针--auto_ptr指针
auto_ptr是C++标准库提供的类模板,头文件<memory>,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同一时候被分给两个拥有者.当 ...
- 【C++智能指针 auto_ptr】
<More Effective C++>ITEM M9他提到auto_ptr.说是当异常产生的时候.怎么释放为对象分配的堆内存,避免反复编写内存释放语句. PS:这里书里面提到函数退出问题 ...
随机推荐
- 在SQL Server中如何快速查找DBCC命令和语法?
DBCC命令非常好用,但是命令很多语法就很多,如何快速记忆呢?是否都要背下来.其实不用,只要能知道每个命令的作用并且记住DBCC HELP命令就可以了. --查找所有的DBCC命令 DBCC HEL ...
- 【精度问题】【HDU2899】Strange fuction
Strange fuction Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- ASP.NET MVC 学习之路-5
本文在于巩固基础 数据库开发模式: 1.数据库优先开发模式 2.模型优先开发模式 EntityFramework学习之一 最简单的一个案例 第一步创建模型 public class Student { ...
- linux下Java环境的配置
linux下Java环境的配置 现在用linux的朋友越来越多了,前几天就有两个朋友问我linux下怎么配置java环境,我想还有很多朋友想了解学习这方面的东西,就写一个完全一点的linux java ...
- DOS下导入dmp文件到Oracle数据库
imp usename/password@SID full=y file= d:\data\xxxx.dmp ignore=y imp system/manager file=bible_db lo ...
- 用Struts2标签实现Map的迭代
最近在做一个论坛,论坛通常分为几个主版块,每一个主版块下面又有几个子版块. 想不出更好的展现方式,最终采用了如下的方法来实现: 用一个Map,HashMap或者Treemap承载之.一个子版块名字对应 ...
- append, appendTo, after区别(preappend、before与这几个原理相同)
append在被选元素结尾插入内容,是被包围在所选元素的标签内的. <script> $('p').append('<a>http</a>'); </scri ...
- Picasso 加载图片到RelativeLayout之解决方案
Picasso 加载图片到ImageView 或者自己的自定义View都是可以直接调用对应API的,但是用into(0直接也加载到RelatieLayout就不好使了,可以这样来: Picasso.w ...
- DataGridview 填写数字
private DataGridViewTextBoxEditingControl CellEdit = null; // 声明 一个 CellEdit private void dgv ...
- React 从0开始 消息传递
React笔记 React 数据决定DOM 以往的做法是通过JS去操作DOM 将数据填充 JSX Jsx javascript xml HTML的结构组装到js中 jsx使用style的时候 不能直接 ...