关于智能指针auto_ptr

时间:2023-03-09 05:36:47
关于智能指针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 ;
}