面试的时候,我们经常会被问到如何自己动手实现智能指针auto_ptr.今天我就一边参考STL库中的源代码,一边将auto_ptr的实现敲一遍。

auto_ptr归根到底是一个模版类,那么这个类要实现哪些功能呢?如下:

/*
一个智能指针应该有以下操作:
1.Auto_ptr<T> ap;            //创建名为ap的为绑定Auto_ptr对象
2.Auto_ptr<T> ap(p);         //创建 ap 的Auto_ptr对象,ap用友指针 p 指向的对象。该构造函数为explicit
3.Auto_ptr<T> ap1(ap2)              //创建名为ap1的Auto_ptr对象,ap1保存原来存在ap2中的指针。将所有权转给ap1,ap2成为未绑定的Auto_ptr对象
4.ap1 = ap2            //将所有权从ap2转给ap1。删除ap1指向的对象并且使ap1指向ap2指向的对象,使ap2成为未绑定的
5.~ap                //析构函数。删除ap指向的对象
6.*ap                                            //返回对ap所绑定对象的引用
7.ap->                                          //返回ap保存的指针
8.ap.reset(p)                                //如果ap与p的值不同,则删除ap指向的独享并且将ap绑定到p
9.ap.release()                               //返回ap所保存的指针并且是ap成为未绑定的
10.ap.get()                                   //返回ap保存的指针
*/

具体代码如下:

 template<class T>
class Auto_ptr {
private:
T *ptr; //真正的指针值
mutable bool owns; //是否拥有该指针
public:
//不可以隐式转化的构造函数
explicit Auto_ptr(T *p = ):ptr(p),owns((bool)p){} //不能隐式转化,例如Auto_ptr<int> Ap = new int(1024) //error
//复制构造函数
//Auto_ptr(const Auto_ptr& a):ptr(a.ptr),owns(a.owns){ a.owns = 0;}
//泛化版的复制构造函数
template <class U>
Auto_ptr(const Auto_ptr<U>& a):ptr(a.ptr),owns(a.owns){ a.owns = ;} //重载赋值操作符
Auto_ptr& operator=(const Auto_ptr& a)
{
if(&a != this) //防止自身赋值
{
if(owns)
delete ptr;
owns = a.owns;
ptr = a.ptr;
a.owns = ;
}
}
//泛化版的重载赋值操作符
template<class U>
Auto_ptr& operator=(Auto_ptr<U>& a)
{
if (&a != this)
{
if(owns)
delete ptr;
owns = a.owns;
ptr = a.ptr;
a.owns = false;
}
return *this;
}
T& operator *() const {return *ptr;}
T* operator ->() const {return ptr;}
T* get() const { return ptr;}
void reset(T *p = )
{
if(owns)
{
if(ptr != p) //如果p 和 ptr的值不同
{
delete ptr; //删除原来指向的对象
} //else付过相同肯定不能删除啊
}
ptr = p; //这里赋值时安全的,机试ptr和p原来相等
}
T* release() const{ owns = false;return ptr;}
~Auto_ptr(){if(owns) {cout << "析构!"<< endl;delete ptr;}}
};

测试代码如下:

 #include<iostream>

 using namespace std;

 int main()
{
Auto_ptr<int> Ap;
Auto_ptr<int> Ap1(new int());
//Auto_ptr<int> Ap2 = new int(1024); //error
//if(Ap == NULL) //error
if(Ap.get() == NULL)
{
cout << "Ap is NULL!" << endl;
}
cout << "Before = Ap1 value is:" << Ap1.get() << endl;
Auto_ptr<int> Ap3 ;
Ap3 = Ap1;
cout << "After = Ap1 value is:" << Ap1.get() << endl;
int *p = Ap3.release();
cout << "Ap3 value is:" << Ap3.get() << endl;
Ap3.reset(new int());
cout << "Ap3 value is:" << Ap3.get() << endl;
return ;
}

测试的结果:

由上图我们可以看到Ap1在 赋值=之前和之后都指向的地址都是00620FB8,说明赋值并没有改变智能指针的指向,只是将拥有的标志owns改变了。通过reset函数可以重新绑定智能指针!

自己动手实现智能指针auto_ptr的更多相关文章

  1. C++智能指针(auto_ptr)详解

    智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...

  2. C++ 智能指针auto_ptr

    template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...

  3. 关于智能指针auto_ptr

    智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...

  4. C++中的智能指针(auto_ptr)

    实际上auto_ptr 仅仅是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势.使用它不必每次都手动调用delete去释放内存.当然有利也有弊,也不是全然完美的. 本 ...

  5. 【C++】智能指针auto_ptr简单的实现

    //[C++]智能指针auto_ptr简单的实现 #include <iostream> using namespace std; template <class _Ty> c ...

  6. 智能指针auto_ptr & shared_ptr

    转载:智能指针auto_ptr 很多人听说过标准auto_ptr智能指针机制,但并不是每个人都天天使用它.这真是个遗憾,因为auto_ptr优雅地解决了C++设计和编码中常见的问题,正确地使用它可以生 ...

  7. C++智能指针 auto_ptr

    C++智能指针 auto_ptr auto_ptr 是一个轻量级的智能指针, 定义于 memory (非memory.h)中, 命名空间为 std. auto_ptr 适合用来管理生命周期比较短或者不 ...

  8. C++智能指针--auto_ptr指针

    auto_ptr是C++标准库提供的类模板,头文件<memory>,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同一时候被分给两个拥有者.当 ...

  9. 【C++智能指针 auto_ptr】

    <More Effective C++>ITEM M9他提到auto_ptr.说是当异常产生的时候.怎么释放为对象分配的堆内存,避免反复编写内存释放语句. PS:这里书里面提到函数退出问题 ...

随机推荐

  1. 查看pid

    可以使用ps -ef | grep httpd查看PID 然后kill –l PID

  2. Objective-C:swift、objective-c、C++、C混合编程

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css); @import url(/ ...

  3. python - 操作RabbitMQ

    python - 操作RabbitMQ     介绍 RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public License开源协议.MQ全称为Mess ...

  4. iBatis 的简单入门

    iBATIS一词来源于“internet”和“abatis”的组合,于2010年6月16号被谷歌托管,改名为MyBatis.是一个基于SQL映射支持Java和·NET的持久层框架. ibatis本是a ...

  5. SQL Server 表字段值转换成字段名称(二)

    上次写了个比较简单的只有两个字段的例子,经要求在写个  3 个字段的示例 ,贴上来与大家共勉一下   如果你们有更好的方法,提供一下, 感激不尽. 示例如下: /*--drop table temp_ ...

  6. 强制关闭myeclipse出现的问题

    重启时,可能会出现打不开关闭前所在的workspace.其他workspace可以正常打开. 今天遇到这个问题,以前就遇到过,但是忘记如何解决了.今天在我等了十多分钟后,神奇的myeclipse自己起 ...

  7. [总结]FFMPEG视音频编解码零基础学习方法

    在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...

  8. ReactiveCocoa入门教程——第一部分

      ReactiveCocoa iOS 翻译    2015-01-22 02:33:37    11471    6    15 本文翻译自RayWenderlich  ReactiveCocoa ...

  9. 【转】iOS-Core-Animation-Advanced-Techniques(一)

     图层树.寄宿图以及图层几何学(一)图层的树状结构 巨妖有图层,洋葱也有图层,你有吗?我们都有图层 -- 史莱克 原文:http://www.cocoachina.com/ios/20150104/1 ...

  10. MVC 文本转换成html显示

    最近在学习ASP.NET MVC,项目中需要将后台传输的HTML文本在前台页面显示:@Html.Raw(HttpUtility.HtmlDecode(ViewBag.DisplayText)).记下来 ...