自己动手实现智能指针auto_ptr
面试的时候,我们经常会被问到如何自己动手实现智能指针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的更多相关文章
- C++智能指针(auto_ptr)详解
智能指针(auto_ptr) 这个名字听起来很酷是不是?其实auto_ptr 只是C++标准库提供的一个类模板,它与传统的new/delete控制内存相比有一定优势,但也有其局限.本文总结的8个问题足 ...
- C++ 智能指针auto_ptr
template<class T> class auto_ptr { public: ); // Item M5 有“explicitfor”// 的描述 template<clas ...
- 关于智能指针auto_ptr
智能指针auto_ptr和shared_ptr也是面试中经常被问到的一个 感觉看auto_ptr的源码反而更加容易理解一些,因为源码的代码量并不大,而且比较容易理解. 本篇主要介绍auto_ptr 其 ...
- 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:这里书里面提到函数退出问题 ...
随机推荐
- Linux下使用w命令和uptime命令查看系统负载
在Linux系统中查询系统CPU和内存的负载(使用率)时,我们通常习惯于使用top.atop或者ps,这篇文章将要给大家介绍如何使用w命令和uptime命令来查看系统的负载情况,对于uptime命令, ...
- 规范javascript书写
空白 缩进 换行限制 if while for do 2. 命名 常量 URL_CONFIG 变量 listLen 函数命名 调用函数 function setStyle(dom, name, v ...
- oracle左右连接 完全连接 有效连接 心得总结
左链接 A表 Left join B表 on 条件 示例 A表 B表 SELECT * FROM A left JOIN B ON A.AID = B.BID; 结果: 左链接查询出来的数 ...
- OSX 10.10+Xcode5.1 无法启动或者安装应用程序到iOS 6.1 simulator
错误症状: OSX 10.10+Xcode5.1 无法启动或者安装应用程序到iOS 6.1 simulator 错误原因: iOS Simulator 内核要使用OSX 系统内核,所以iOS Simu ...
- atoi、stoi、strtoi区别
首先atoi和strtol都是c里面的函数,他们都可以将字符串转为int,它们的参数都是const char*,因此在用string时,必须调c_str()方法将其转为char*的字符串.或者atof ...
- RSA签名验签
import android.util.Base64; import java.security.KeyFactory; import java.security.PrivateKey; import ...
- nest 'for' loop.
/* nest for loop demo. Note that,'upside' triangle controls 'inner condition'. */ import kju.print.P ...
- [转]关于java中的 sychronized 同步方法 与 同步块的理解
首先,需要说明一点,也是最重要的一点,无论是同步方法 还是 同步块 都是只针对同一个对象的多线程而言的,只有同一个对象产生的多线程,才会考虑到 同步方法 或者是 同步块,如果定义多个实例的同步,可以考 ...
- 段落排版--中文字间距、字母间距(letter-spacing, word-spacing)
中文字间隔.字母间隔设置: 如果想在网页排版中设置文字间隔或者字母间隔就可以使用 letter-spacing 来实现,如下面代码: h1{ letter-spacing:50px; } ... ...
- 【vc】1_Windows程序内部运行机制
创建一个Win32应用程序步骤: 1.编写WinMain函数; 2.创建窗口(步骤如下): a.设计(一个)窗口类(WNDCLASS) b.注册(该)窗口类. c.创建窗口. d.显示并更新窗口. 3 ...