C++中的智能指针实际上是代理模式与RAII的结合。

自定义unique_ptr,主要是release()和reset()。代码如下。

#include <iostream>
using namespace std; template<typename T>
class my_unique_ptr {
public:
my_unique_ptr(T *p = 0): pointee(p) {};
~my_unique_ptr() {
delete pointee;
}
T &operator * () const {
return *pointee;
}
T *operator -> () const {
return pointee;
}
T *get() {
return pointee;
}
T *release() {
T *oldPointee = pointee;
pointee = 0;
return oldPointee;
}
void reset(T *p = 0) {
if(pointee != p) {
delete pointee;
pointee = p;
}
}
private:
my_unique_ptr(const my_unique_ptr<T> &rhs);
my_unique_ptr<T> &operator = (const my_unique_ptr<T> &rhs); T *pointee;
}; struct C {
~C() {
cout << "destructor" << endl;
};
void print() {
cout << "print" << endl;
};
}; int main() {
my_unique_ptr<C> u1;
cout << u1.get() << endl; //0 my_unique_ptr<C> u2(new C());
u2->print(); //print my_unique_ptr<C> u3(u2.release());
cout << u2.get() << endl; //0
u3->print(); //print my_unique_ptr<C> u4;
u4.reset(u3.release());
cout << u3.get() << endl; //0
u4->print(); //print return 0; //destructor
}

自定义shared_ptr,主要是引用计数,代码如下。

#include <iostream>
using namespace std; template<typename T>
class my_shared_ptr {
public:
my_shared_ptr(T *p = 0): pointee(p), count(new size_t(0)) {
if(p) ++*count;
};
my_shared_ptr(const my_shared_ptr<T> &rhs): pointee(rhs.pointee), count(rhs.count) {
++*count;
}
my_shared_ptr<T> &operator = (const my_shared_ptr<T> &rhs) {
if(&rhs != this) {
decrease_count(); pointee = rhs.pointee;
count = rhs.count;
++*count;
}
return *this;
}
~my_shared_ptr() {
decrease_count();
}
size_t use_count() {
return *count;
}
T &operator * () const {
return *pointee;
}
T *operator -> () const {
return pointee;
}
private:
void decrease_count() {
if(--*count == 0) {
delete pointee;
delete count;
}
} T *pointee;
size_t *count;
}; struct C {
~C() {
cout << "destructor" << endl;
};
void print() {
cout << "print" << endl;
};
}; int main() {
my_shared_ptr<C> p1;
cout << "p1: " << p1.use_count() << endl; //p1: 0 my_shared_ptr<C> p2(new C());
cout << "p2: " << p2.use_count() << endl; //p2: 1 my_shared_ptr<C> p3(p2);
cout << "p3: " << p3.use_count() << endl; //p3: 2 my_shared_ptr<C> p4 = p3;
cout << "p4: " << p4.use_count() << endl; //p4: 3 {
my_shared_ptr<C> p5(p4);
cout << "p5: " << p5.use_count() << endl; //p5: 4
} cout << "p2: " << p2.use_count() << endl; //p2: 3
cout << "p3: " << p3.use_count() << endl; //p3: 3
cout << "p4: " << p4.use_count() << endl; //p4: 3 (*p4).print(); //print
p4->print(); //print return 0; //destructor
}

C++实现具有基本功能的智能指针的更多相关文章

  1. Binder学习笔记(十一)—— 智能指针

    轻量级指针 Binder的学习历程爬到驱动的半山腰明显感觉越来越陡峭,停下业务层的学习,补补基础层知识吧,这首当其冲的就是智能指针了,智能指针的影子在Android源码中随处可见.打开framewor ...

  2. C++ 11 智能指针 lamda 以及一个 围棋程序

    lamda表达式使用 char* p = "Hello world"; ,nl = ; for_each(p,p+, [&](char i){ if(i=='e') ne+ ...

  3. Rust入坑指南:智能指针

    在了解了Rust中的所有权.所有权借用.生命周期这些概念后,相信各位坑友对Rust已经有了比较深刻的认识了,今天又是一个连环坑,我们一起来把智能指针刨出来,一探究竟. 智能指针是Rust中一种特殊的数 ...

  4. 02 | 自己动手,实现C++的智能指针

    第一步:针对单独类型的模板 为了完成智能指针首先第一步的想法. class shape_wrapper { public: explicit shape_wrapper( shape* ptr = n ...

  5. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  6. c++ auto_ptr智能指针

    c++ auto_ptr智能指针 该类型在头文件memory中,在程序的开通通过 #include<memory> 导入,接下来讲解该智能指针的作用和使用. 使用方法: auto_ptr& ...

  7. C++智能指针简单剖析

    导读 最近在补看<C++ Primer Plus>第六版,这的确是本好书,其中关于智能指针的章节解析的非常清晰,一解我以前的多处困惑.C++面试过程中,很多面试官都喜欢问智能指针相关的问题 ...

  8. [4] 智能指针boost::scoped_ptr

    [1]boost::scoped_ptr简介 boost::scoped_ptr属于boost库,定义在namespace boost中,包含头文件#include <boost/scoped_ ...

  9. [6] 智能指针boost::weak_ptr

    [1]boost::weak_ptr简介 boost::weak_ptr属于boost库,定义在namespace boost中,包含头文件 #include<boost/weak_ptr.hp ...

随机推荐

  1. 天梯赛决赛 L2-1.红色警报 并查集

    L2-013. 红色警报 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 战争中保持各个城市间的连通性非常重要.本题要求你编写一 ...

  2. 皓轩的jquery mobile之路(二)

    jQuery Mobile 使用 HTML5 & CSS3 最小的脚本来布局网页. 编写代码要注意最外层div需要添加data-role="page" ,标题需要添加dat ...

  3. PAT (Advanced Level) 1022. Digital Library (30)

    简单模拟题. 写的时候注意一些小优化,小心TLE. #include<iostream> #include<cstring> #include<cmath> #in ...

  4. ssh密钥登录及远程执行命令

    以192.168.1.104作为客户机 以192.168.1.103作为服务器 使用密钥登录 创建密钥对 在SSH客户机创建用户秘钥对 ssh-keygen -t rsa 之后全回车即可 将会在~/. ...

  5. typedef和block

    为block类型对象取别名 1.没有使用typedef的情况 int (^block_add)(int, int) = ^(int value1, int value2) { return value ...

  6. 10个带源码的充满活力的Web设计教程

    10个带源码的充满活力的Web设计教程 2013-08-02 16:47 佚名 OSCHINA编译 我要评论(0) 字号:T | T Web设计师必须了解各种各样的Web设计风格,这才能让他或者她在设 ...

  7. nexus 中央仓库

    nexus 中央仓库 下载地址:http://www.sonatype.org/nexus/archived 下载最新版本 mkdir -p /opt/local/nexus tar zxvf nex ...

  8. [Unity Shader]光照模型对物体的假设

    什么是光照模型 光照模型就是模拟光在物体间的传递过程,以确保物体可见表面每一点的亮度和颜色. 当光照射到一个物体表面时,光可能被吸收.反射或折射.反射和折射的光使物体可见.如果入射光全部被吸收,物体将 ...

  9. MySQL的IP处理函数inet_aton()和inet_ntoa()

    给出一个作为字符串的网络地址的"点地址"(如127.0.0.1)表示,返回一个代表该地址数值的整数.地址可以是4或8比特地址. mysql> SELECT inet_aton ...

  10. Exception和RuntimeException的区别

    Exception:在程序中必须使用try...catch进行处理. RuntimeException:可以不使用try...catch进行处理,但是如果有异常产生,则异常将由JVM进行处理.