文档章节

智能指针的设计与实现

borey
 borey
发布于 2014/09/11 00:31
字数 499
阅读 109
收藏 0
#include <cstdio>
#include <atomic>
 
class CRefCount
{
public:
    CRefCount() : m_nCount(0) {}
    unsigned AddRef() 
    {
      return ++m_nCount;
    }
    unsigned DecRef()
    {
      return --m_nCount;
    }
private:
    CRefCount(const CRefCount&);
    CRefCount& operator =(const CRefCount&);
    std::atomic<unsigned> m_nCount;
};
 
template <class T>
class CSmartPointer
{
public:
    CSmartPointer();
    virtual ~CSmartPointer();

    CSmartPointer(T* ptr);
    CSmartPointer(CSmartPointer<T>& sp);
    CSmartPointer<T>& operator =(T* ptr);
    CSmartPointer<T>& operator =(CSmartPointer<T>& sp);
 
    operator bool();
    T* operator ->();
    T& operator *();    
    T* Get();
    CRefCount* GetRef();

private:
    void Remove();
 
private:
    T*          m_ptr;
    CRefCount*  m_pCountRef;
};
 
template <class T>
CSmartPointer<T>::CSmartPointer()
:m_ptr(NULL)
{
    m_pCountRef = new CRefCount;
    if (m_pCountRef)
        m_pCountRef->AddRef();
}

template <class T>
CSmartPointer<T>::~CSmartPointer()
{
    Remove();
}
 
template <class T>
CSmartPointer<T>::CSmartPointer(T* ptr)
{
    //printf("CSmartPointer<T>::CSmartPointer(T* ptr) %s\n", __FUNCTION__);
    m_ptr = ptr;
    m_pCountRef = new CRefCount;
    if (m_pCountRef)
        m_pCountRef->AddRef();
}
 
template <class T>
CSmartPointer<T>::CSmartPointer(CSmartPointer<T>& sp)
{
    //printf("CSmartPointer<T>::CSmartPointer(CSmartPointer<T>& sp) %s\n", __FUNCTION__);
    m_ptr = sp.Get();
    m_pCountRef = sp.GetRef();
    if (m_pCountRef)
        m_pCountRef->AddRef();
}

template <class T>
CSmartPointer<T> & CSmartPointer<T>::operator =(T* ptr)
{
    //printf("CSmartPointer<T> & CSmartPointer<T>::operator =(T* ptr) %s\n", __FUNCTION__);
    if (m_ptr == ptr)
        return *this;
 
    Remove();
    m_ptr = ptr;
    m_pCountRef = new CRefCount;
    if (m_pCountRef)
        m_pCountRef->AddRef();
 
    return *this;
}

template <class T>
CSmartPointer<T> & CSmartPointer<T>::operator =(CSmartPointer<T>& sp)
{
    //printf("CSmartPointer<T> & CSmartPointer<T>::operator =(CSmartPointer<T>& sp) %s\n", __FUNCTION__);
    if (this == &sp)
        return *this;
 
    Remove();
    m_ptr = sp.Get();
    m_pCountRef = sp.GetRef();
    if (m_pCountRef)
        m_pCountRef->AddRef();
 
    return *this;
}
 
template<class T>
void CSmartPointer<T>::Remove()
{
    if (m_pCountRef && m_pCountRef->DecRef() <= 0)
    {
        delete m_ptr;
        m_ptr = NULL;
        delete m_pCountRef;
        m_pCountRef = NULL;
    }
}
 
template <class T>
CSmartPointer<T>::operator bool()
{
    return (m_ptr != NULL);
}
 
template <class T>
T*  CSmartPointer<T>::operator->()
{
    return m_ptr;
}
 
template <class T>
T&  CSmartPointer<T>::operator *()
{
    return *m_ptr;
}
 
template <class T>
T* CSmartPointer<T>::Get()
{
    return m_ptr;
}
 
template<class T>
CRefCount* CSmartPointer<T>::GetRef()
{
    return m_pCountRef;
}
 
struct MyStruct
{
    int a;
    int b;
    MyStruct() : a(0), b(0)
    {
       printf("MyStruct structure!\n");
    }
    ~MyStruct()
    {
       printf("MyStruct destructor! a = %d, b = %d\n", a, b);
    }
    void print()
    {
       printf("MyStruct print() a = %d, b = %d\n", a, b);
   }
};
 
//测试智能指针
void test_SmartPointer()
{
    CSmartPointer<MyStruct> ms1(new MyStruct);
    if (ms1)
    {
        ms1->a = 10;
        ms1->b = 20;
        ms1->print();
    }
 
    CSmartPointer<MyStruct> ms2;
    ms2 = ms1;
    if (ms2)
    {
        ms2->a = 100;
        ms2->b = 200;
        ms2->print();
    }
 
    CSmartPointer<MyStruct> ms3(ms2);
    if (ms3)
    {
        ms3->a = 1000;
        ms3->b = 2000;
        ms3->print();
    }
    ms3 = new MyStruct;
    if (ms3)
    {
        ms3->a = 3000;
        ms3->b = 4000;
        ms3->print(); 
    }

}
 
int main(int argc, char* argv[])
{
    test_SmartPointer();//函数调用是为了在main退出之前就能看到指针被释放。
 
    //system("PAUSE");
    return 0;
}

运行结果:

$ ./a.out 
MyStruct structure!
MyStruct print() a = 10, b = 20
MyStruct print() a = 100, b = 200
MyStruct print() a = 1000, b = 2000
MyStruct structure!
MyStruct print() a = 3000, b = 4000
MyStruct destructor! a = 3000, b = 4000
MyStruct destructor! a = 1000, b = 2000

如有问题欢迎指出,谢谢~~

© 著作权归作者所有

borey
粉丝 28
博文 55
码字总数 31182
作品 0
深圳
程序员
私信 提问
加载中

评论(2)

borey
borey 博主

引用来自“JellyThink”的评论

做一个简单的Code Review:
1.>virtual ~CSmartPointer();
没有必要定义析构为虚函数;

2.>T* operator ->();
智能指针的wrapper,重点是在实现对“*”和“->”操作符的重载,没有实现对“*”操作符的重载;

3.CSmartPointer类的成员变量定义成了protected,如果没有这样做的理由,还是定义成private更好一些;

4.if (m_uCount > 0)
{
Remove();
}
这段代码,会导致其它指针变量失效。

推荐阅读这篇文章:http://www.jellythink.com/archives/301
其中有一个智能指针的实现。
谢谢你! 1,virtual析构函数还是保留或将CSmartPoint定义为不可继承 2,应该要实现operator*() 3,应该定义为private 4,m_uCount这里定义为变量错了,应该使用指针,我也重新全部改了,参照上面的文章实现了count线程安全的版本 程序更新了,能再帮我看一下吗?
果冻想
果冻想
做一个简单的Code Review:
1.>virtual ~CSmartPointer();
没有必要定义析构为虚函数;

2.>T* operator ->();
智能指针的wrapper,重点是在实现对“*”和“->”操作符的重载,没有实现对“*”操作符的重载;

3.CSmartPointer类的成员变量定义成了protected,如果没有这样做的理由,还是定义成private更好一些;

4.if (m_uCount > 0)
{
Remove();
}
这段代码,会导致其它指针变量失效。

推荐阅读这篇文章:http://www.jellythink.com/archives/301
其中有一个智能指针的实现。
数据结构库——智能指针的实现(下)

1,SmartPointer 被设计成每次只允许一个智能指针对象指向一片堆空间,也就限制了智能指针的运用,不能够运用于LinkList; 2,本节完成 SharedPointer 的具体实现: 3,SharedPointer 设计要...

子宇24
05/25
0
0
智能指针的设计

智能指针是c++中一个很重要的概念,其实吧,如果c++设计得足够好,智能指针本不应该出现的,c++标准库的智能指针主要解决了两个问题,一个问题是内存释放问题,另一个问题是指针复用问题,也...

晨曦之光
2012/04/10
136
0
C++中智能指针的设计和使用

转载请标明出处,原文地址:http://blog.csdn.net/hackbuteer1/article/details/7561235 智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的...

陈国成
2017/06/17
0
0
Chromium的智能指针/引用计数/Callback/Bind

这四个东西对使用者来说不难,看懂代码注释里的例子即可,预计1小时左右看懂全部。要去理解其设计思想的话最需要掌握的是模板类的使用,但一般使用者完全不用关心怎么设计的。 使用者的学习路...

zhangyujsj
2015/08/22
146
0
cocos2dx3.0的内存管理机制

cocos2d-x中的内存管理机制可以看成给予智能指针的一个变体,但它同时是程序员进而一项实用垃圾回收机制那样不需要声明智能指针 1,引用计数 cocos2d中所有的对象几乎都集成自Ref基类。Ref基...

亮亮同学
01/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

面试官,Java8 JVM内存结构变了,永久代到元空间

在文章《JVM之内存结构详解》中我们描述了Java7以前的JVM内存结构,但在Java8和以后版本中JVM的内存结构慢慢发生了变化。作为面试官如果你还不知道,那么面试过程中是不是有些露怯?作为面试...

程序新视界
1分钟前
0
0
读书笔记:深入理解ES6 (八)

第八章 迭代器(Iterator)与生成器(Generator) 第1节 循环语句的问题   在循环、多重循环中,通过变量来跟踪数组索引的行为容易导致程序出错。迭代器的出现旨在消除这种复杂性,并减少循...

张森ZS
2分钟前
1
0
Elasticsearch 实战(一) - 简介

官腔 Elasticsearch,分布式,高性能,高可用,可伸缩的搜索和分析系统 基本等于没说,咱们慢慢看 1 概述 百度:我们比如说想找寻任何的信息的时候,就会上百度去搜索一下,比如说找一部自己喜...

JavaEdge
6分钟前
0
0
【jQuery基础学习】11 jQuery性能简单优化

本文转载于:专业的前端网站➦【jQuery基础学习】11 jQuery性能简单优化 关于性能优化 合适的选择器 $("#id")会直接调用底层方法,所以这是最快的。如果这样不能直接找到,也可以用find方法继...

前端老手
15分钟前
3
0
重磅发布 | 全球首个云原生应用标准定义与架构模型 OAM 正式开源

导读:2019 年 10 月 17 日,阿里巴巴合伙人、阿里云智能基础产品事业部总经理蒋江伟(花名:小邪)在 Qcon 上海重磅宣布,阿里云与微软联合推出开放应用模型 Open Application Model (OAM...

阿里云官方博客
18分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部