面试的时候,我们经常会被问到如何自己动手实现智能指针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. Android开发:最详细的 Toolbar 开发实践总结

    最详细的 Toolbar 开发实践总结 过年前发了一篇介绍 Translucent System Bar 特性的文章 Translucent System Bar 的最佳实践,收到很多开发者的关注和反 ...

  2. codevs 1170 双栈排序

    /* 好题啊 好题啊 而然还是看了一眼题解啊 有那么一点思路 但是离写出代码还很远 考虑必须分开放倒两个栈里的情况 即存在i<j<k 有 a[k]<a[i]<a[j] 这里RM ...

  3. (转)smarty实现多级分类的方法

    --http://www.aspku.com/kaifa/php/44679.html 这篇文章主要介绍了smarty实现多级分类的方法,涉及循环读取的技巧,非常具有实用价值,需要的朋友可以参考下   ...

  4. SQL语句之二建表

    use Test --进入需要建表的数据库if exists(select * from sysobjects where name='MyTable')--表是否已经存在drop table MyT ...

  5. IDEA SVN1.8 问题解决

    转自 http://blog.jetbrains.com/idea/2013/12/subversion-1-8-and-intellij-idea-13/

  6. &amp与&

       

  7. 取出当前会话的sid等

    select distinct sess.SID     db_sid,                sess.SERIAL# db_serial#,                process. ...

  8. Deep Learning 学习随记(五)Deep network 深度网络

    这一个多周忙别的事去了,忙完了,接着看讲义~ 这章讲的是深度网络(Deep Network).前面讲了自学习网络,通过稀疏自编码和一个logistic回归或者softmax回归连接,显然是3层的.而这 ...

  9. XE6 /XE8 & IOS开发之免证书真机调试三步走,生成iPA文件并安装到其它苹果设备上

    XE6 & IOS开发之免证书真机调试(1):颁发属于自己的App签名证书(有图有真相) XE6 & IOS开发之免证书真机调试(2):连接真机并运行App(有图有真相) XE6 &a ...

  10. C#堆栈原理(我有两个例子测试你到底会不会)

    背景 上次写了一篇文章关于try finnally的一些疑问(被我用windows live覆盖了,草),后来经过大神们解释,我明白了在我理解了try.finnally运行原理后,还欠缺的就是关于值类 ...