我的另一个智能指针

KRYObject.h

#pragma once

class KRYObject
{
    template<typename T>
    friend class KRYRefPtr;
    template<typename T>
    friend class KRYWeakPtr;
private:
    struct KRYRefCount
    {
        KRYRefCount()
        {
            //able = true;
            refCount = 0;
            weakCount = 1;
        }
        //bool able;
        int refCount;
        int weakCount;
    };
protected:
    KRYObject()
    {
        m_count = 0;
    }
    virtual ~KRYObject()
    {
        if (0 != m_count)
        {
            //m_count->able = false;
            m_count->weakCount -= 1;
            if (m_count->refCount <= 0 && m_count->weakCount <= 0)
            {
                delete m_count;
                m_count = 0;
            }
        }
    }
    inline void addRef()
    {
        m_count->refCount += 1;
    }
    inline KRYRefCount* subRef()
    {
        KRYRefCount *ret = m_count;
        m_count->refCount -= 1;
        if (m_count->refCount <= 0)
        {
            ret = 0;
            delete this;
        }
        return ret;
    }
private:
    inline KRYRefCount* getCount()const
    {
        if (0 == m_count) { m_count = new KRYRefCount(); }
        return m_count;
    }
private:
    mutable KRYRefCount *m_count;
};
template<typename T>
class KRYRefPtr
{
    template<typename U>
    friend class KRYRefPtr;
    template<typename U>
    friend class KRYWeakPtr;
private:
    void subRef()
    {
        if (0 != m_count)
        {
            m_count = m_ptr->subRef();
            if (0 == m_count)
            {
                m_ptr = 0; m_count = 0;
            }
        }
    }
    template<typename U>
    void init(const U *ptr)
    {
        m_ptr = (U*)ptr; m_count = 0;
        if (0 != m_ptr){ m_count = ptr->getCount(); m_count->refCount += 1; }
    }
    template<typename U>
    void init(const KRYRefPtr<U> &ptr)
    {
        m_ptr = ptr.m_ptr; m_count = ptr.m_count;
        if (0 != m_count){ m_count->refCount += 1; }
    }
    template<typename U>
    void reset(const U *ptr)
    {
        if (0 != ptr){ ptr->getCount()->refCount += 1; }
        subRef();
        m_ptr = (U*)ptr; m_count = 0;
        if (0 != ptr){ m_count = ptr->m_count; }
    }
    template<typename U>
    void reset(const KRYRefPtr<U> &ptr)
    {
        if (0 != ptr.m_count){ ptr.m_count->refCount += 1; }
        subRef();
        m_ptr = ptr.m_ptr;
        m_count = ptr.m_count;
    }
    template<typename U>
    KRYRefPtr(U *ptr, KRYObject::KRYRefCount *count)
    {
        m_ptr = 0; m_count = 0;
        if (0 != count && count->refCount > 0)
        {
            m_ptr = ptr;
            m_count = count;
            m_count->refCount += 1;
        }
    }
public:
    KRYRefPtr(){ m_ptr = 0; m_count = 0; }
    ~KRYRefPtr() { subRef(); }
    KRYRefPtr(const KRYRefPtr& ptr)
    {
        init(ptr);
    }
    KRYRefPtr operator=(const KRYRefPtr& ptr)
    {
        reset(ptr);
        return *this;
    }
    template<typename U>
    KRYRefPtr(U *ptr)
    {
        init(ptr);
    }
    template<typename U>
    KRYRefPtr<T>& operator=(U *ptr)
    {
        reset(ptr);
        return *this;
    }

    template<typename U>
    KRYRefPtr(const KRYRefPtr<U> &ptr)
    {
        init(ptr);
    }
    template<typename U>
    KRYRefPtr<T>& operator=(const KRYRefPtr<U> &ptr)
    {
        reset(ptr);
        return *this;
    }

    T* operator->() const{ return m_ptr; }
    T& operator*() const { return *m_ptr; }
    operator bool() const { return m_ptr != 0; }
    T* getPtr() const { return m_ptr; }
    void reset(){ subRef(); m_ptr = 0; m_count = 0; }
private:
    T *m_ptr;
    KRYObject::KRYRefCount *m_count;
};
template<typename T>
class KRYWeakPtr
{
    template<typename U>
    friend class KRYWeakPtr;
private:
    void subWeak()
    {
        if (0 != m_count)
        {
            m_count->weakCount -= 1;
            if (m_count->refCount <= 0 && m_count->weakCount <= 0)
            {
                delete m_count;
                m_ptr = 0;
                m_count = 0;
            }
        }
    }
    template<typename U>
    void init(const KRYWeakPtr<U> &ptr)
    {
        m_ptr = ptr.m_ptr;
        m_count = ptr.m_count;
        if (0 != m_count){ m_count->weakCount += 1; }
    }
    template<typename U>
    void init(const KRYRefPtr<U> &ptr)
    {
        m_ptr = ptr.m_ptr;
        m_count = ptr.m_count;
        if (0 != m_count){ m_count->weakCount += 1; }
    }
    template<typename U>
    void init(const U *ptr)
    {
        m_ptr = (U*)ptr; m_count = 0;
        if (0 != ptr){ m_count = ptr->getCount(); m_count->weakCount += 1; }
    }
    template<typename U>
    void reset(const KRYWeakPtr<U> &ptr)
    {
        if (0 != ptr.m_count){ ptr.m_count->weakCount += 1; }
        subWeak();
        m_ptr = ptr.m_ptr;
        m_count = ptr.m_count;
    }
    template<typename U>
    void reset(const KRYRefPtr<U> &ptr)
    {
        if (0 != ptr.m_count){ ptr.m_count->weakCount += 1; }
        subWeak();
        m_ptr = ptr.m_ptr;
        m_count = ptr.m_count;
    }
    template<typename U>
    void reset(const U *ptr)
    {
        if (0 != ptr){ ptr->getCount()->weakCount += 1; }
        subWeak();
        m_ptr = ptr; m_count = 0;
        if (0 != ptr){ m_count = ptr->m_count;}
    }
public:
    KRYWeakPtr(){ m_ptr = 0; m_count = 0; }
    ~KRYWeakPtr(){ subWeak(); }
    KRYWeakPtr(const KRYWeakPtr &ptr)
    {
        init(ptr);
    }
    KRYWeakPtr& operator=(const KRYWeakPtr &ptr)
    {
        reset(ptr); return *this;
    }

    template<typename U>
    KRYWeakPtr(const KRYWeakPtr<U> &ptr)
    {
        init(ptr);
    }
    template<typename U>
    KRYWeakPtr& operator=(const KRYWeakPtr<U> &ptr)
    {
        reset(ptr); return *this;
    }

    template<typename U>
    KRYWeakPtr(const KRYRefPtr<U> &ptr)
    {
        init(ptr);
    }
    template<typename U>
    KRYWeakPtr& operator=(const KRYRefPtr<U> &ptr)
    {
        reset(ptr); return *this;
    }

    template<typename U>
    KRYWeakPtr(const U *ptr)
    {
        init(ptr);
    }
    template<typename U>
    KRYWeakPtr& operator=(const U *ptr)
    {
        reset(ptr); return *this;
    }

    KRYRefPtr<T> lock()
    {
        return KRYRefPtr<T>(m_ptr, m_count);
    }

    T* operator->() const{ return m_ptr; }
    T& operator*() const { return *m_ptr; }
    //operator bool() const { return m_count != 0 && m_count->able; }
    operator bool() const { return m_count != 0 && m_count->refCount > 0; }
    T* getPtr() const
    {
        T *ptr = 0;
        //if (m_count != 0 && m_count->able)
        if (m_count != 0 && m_count->refCount > 0)
        {
            ptr = m_ptr;
        }
        return ptr;
    }
    void reset(){ subWeak(); m_ptr = 0; m_count = 0; }
private:
    T *m_ptr;
    KRYObject::KRYRefCount *m_count;
};

template<typename T, typename U>
bool operator==(const KRYRefPtr<T>& a, const KRYRefPtr<U>& b) { return (a.getPtr() == b.getPtr()); }
template<typename T, typename U>
bool operator==(const KRYRefPtr<T>& a, const U* b) { return (a.getPtr() == b); }
template<typename T, typename U>
bool operator==(const U* a, const KRYRefPtr<T>& b) { return (a == b.getPtr()); }

template<typename T, typename U>
bool operator!=(const KRYRefPtr<T>& a, const KRYRefPtr<U>& b) { return (a.getPtr() != b.getPtr()); }
template<typename T, typename U>
bool operator!=(const KRYRefPtr<T>& a, const U* b) { return (a.getPtr() != b); }
template<typename T, typename U>
bool operator!=(const U* a, const KRYRefPtr<T>& b) { return (a != b.getPtr()); }

template<typename T, typename U>
bool operator==(const KRYWeakPtr<T>& a, const KRYWeakPtr<U>& b) { return (a.getPtr() == b.getPtr()); }
template<typename T, typename U>
bool operator==(const KRYWeakPtr<T>& a, const U* b) { return (a.getPtr() == b); }
template<typename T, typename U>
bool operator==(const U* a, const KRYWeakPtr<T>& b) { return (a == b.getPtr()); }

template<typename T, typename U>
bool operator!=(const KRYWeakPtr<T>& a, const KRYWeakPtr<U>& b) { return (a.getPtr() != b.getPtr()); }
template<typename T, typename U>
bool operator!=(const KRYWeakPtr<T>& a, const U* b) { return (a.getPtr() != b); }
template<typename T, typename U>
bool operator!=(const U* a, const KRYWeakPtr<T>& b) { return (a != b.getPtr()); }

test.cpp

#include "KRYObject.h"
class Base:public KRYObject
{
public:
    Base(){ cout << "Base()" << endl; }
    virtual ~Base(){ cout << "~Base()" << endl; }
    virtual void fun(){ cout << "Base::fun()" << endl; }
};
class Device :public Base
{
public:
    Device(){ cout << "Device()" << endl; }
    ~Device(){ cout << "~Device()" << endl; }
    virtual void fun(){ cout << "Device::fun()" << endl; }
};
void main()
{
    /*KRYRefPtr<Device> device = new Device();
    {
        KRYRefPtr<Base> base = device;
        base->fun();
    }
    device->fun();*/
    KRYWeakPtr<Base> weak;
    {
        KRYRefPtr<Device> device = new Device();
        weak = device;
    }
    if (weak){ weak->fun(); }
}
时间: 2024-10-13 16:03:52

我的另一个智能指针的相关文章

【转】 C++易混知识点4: 自己编写一个智能指针(Reference Counting)学习auto_ptr和reference counting

这篇文章建大的介绍了如何编写一个智能指针. 介绍: 什么是智能指针?答案想必大家都知道,智能指针的目的就是更好的管理好内存和动态分配的资源,智能指针是一个智能的指针,顾名思义,他可以帮助我们管理内存.不必担心内存泄露的问题.实际上,智能指针是一个行为类似于指针的类,通过这个类我们来管理动态内存的分配和销毁.方便客户端的使用.相比于一般指针,智能指针主要体现在它使用的容易和便捷性. 转载请注明出处: http://blog.csdn.net/elfprincexu 使用一般指针的问题: 一般情况下

[cocos2dx注意事项014]一个用于cocos2dx对象智能指针模板

现在,C++有许多实现智能指针,一个更无所谓.哈. 这种智能指针是专为cocos2dx 2.2.x自定义.主要的易用性,同时必须遵循现有的cocos2dx内存管理.特殊实现这样的智能指针.无需在使用时考虑retain要么release操作.须要new或delete操作! 以下是实现代码 //在非常多时候,类的成员是CCObject的子对象,为了保证对其正常使用,又要遵循cocos2dx的内存管理.特实现了这种一个智能指针,方便使用. #ifndef _X_COCOS_PTR_H_ #define

[cocos2dx笔记014]一个用于cocos2dx的对象智能指针模板

现在C++智能指针有无数个实现了,多一个也无所谓.哈. 这个智能指针是专门为cocos2dx 2.2.x定制的.主要是为了方便使用,同时又要遵循现有的cocos2dx的内存管理.特实现这样一个智能指针.在使用的时候不需要考虑retain或release操作,也不需要new或delete操作! 下面是实现代码 //在很多时候,类的成员是CCObject的子对象,为了保证对其正常使用,又要遵循cocos2dx的内存管理,特实现了这样的一个智能指针,方便使用. #ifndef _X_COCOS_PTR

C++智能指针简单剖析

导读 最近在补看<C++ Primer Plus>第六版,这的确是本好书,其中关于智能指针的章节解析的非常清晰,一解我以前的多处困惑.C++面试过程中,很多面试官都喜欢问智能指针相关的问题,比如你知道哪些智能指针?shared_ptr的设计原理是什么?如果让你自己设计一个智能指针,你如何完成?等等--.而且在看开源的C++项目时,也能随处看到智能指针的影子.这说明智能指针不仅是面试官爱问的题材,更是非常有实用价值. 下面是我在看智能指针时所做的笔记,希望能够解决你对智能指针的一些困扰. 目录

C++智能指针剖析(下)boost::shared_ptr&amp;其他

1. boost::shared_ptr 前面我已经讲解了两个比较简单的智能指针,它们都有各自的优缺点.由于 boost::scoped_ptr 独享所有权,当我们真真需要复制智能指针时,需求便满足不了了,如此我们再引入一个智能指针,专门用于处理复制,参数传递的情况,这便是如下的boost::shared_ptr. boost::shared_ptr 属于 boost 库,定义在 namespace boost 中,包含头文件#include<boost/smart_ptr.hpp> 便可以使

第十一章:使用智能指针管理对象资源

前言 在前面的文章中,细致地分析了构造函数,拷贝构造函数,赋值运算符,析构函数这几个类中最重要函数的用法. 如果严格地遵循这些做法,可以消除绝大部分资源管理的问题. 然而,要想更灵活的使用对象中的资源,仅仅这些还不够.譬如,若你想自己控制对象资源的生命周期(不要在作用域结束的时候自动被析构掉),那就应当好好考虑下智能指针了. 有人说,智能指针是属于设计模式范畴的产物,这么说有点偏激,但也确实有点道理. 问题分析 我们假定有一个投资类Investment: 1 class Investment 2

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

本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): 1.实现基本通信框架,包括对游戏的需求分析.设计及开发环境和通信框架的搭建: 2.实现网络底层操作,包括创建线程池.序列化网络包等: 3.实战演练,实现类似于CS反恐精英的3D对战网络游戏: 技术要点:C++面向对象思想.网络编程.Qt界面开发.Qt控件知识.Boost智能指针.STL算法.STL.

C++智能指针类模板

1.智能指针本质上是一个对象,这个对象可以像原生的一样来进行使用.原因是智能指针对象对应的类中,将指针相关的操作都进行了重载操作处理,所以才会达到这种像是原生的效果. 2.智能指针的意义: 现在C++开发库中最重要的类模板之一 C++中自动内存管理的主要手段 能够在很大程度上避开内存相关的问题 3.在QT中开发库中也提供了智能指针类模板,在STL标准库中也提供了,在c++的标准库忘了什么名了中也提供了智能指针类模板.所以智能指针类模板在C++中的地位很重要 4.STL中的智能指针类模板 auto

第37课 智能指针分析

1. 永恒的话题:内存泄漏 (1)动态申请堆空间,用完后不归还 (2)C++语言中没有垃圾回收的机制 (3)指针无法控制所指堆空间的生命周期 [编程实验]内存泄漏 #include <iostream> #include "IntArray.h" using namespace std; class Test { int i; public: Test(int i) { this->i = i; cout << "Test(int i)"