`
sogo6
  • 浏览: 113755 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

用模板实现引用计数

    博客分类:
  • C++
 
阅读更多

#ifndef T_NO_ANSI_CASTS 
# define T_REINTERPRET_CAST(type,pointer) reinterpret_cast< type >(pointer)
# define T_STATIC_CAST(type,pointer) static_cast< type >(pointer)
# define T_CONST_CAST(type,pointer) const_cast< type >(pointer)
#else
# define RW_REINTERPRET_CAST(type,pointer) (type)pointer
# define RW_STATIC_CAST(type,pointer) (type)pointer
# define RW_CONST_CAST(type,pointer) (type)pointer
#endif /* T_NO_ANSI_CASTS */

class CReference 
{
public:
    CReference(){}
    virtual ~CReference() {}

    void addReference()
    {
        refCount_ ++;
    }

    int removeReference()
    {
        return refCount_ --;
    }

    int references() const 
    {
        return refCount_;
    }

private:
    volatile int  refCount_;
    //unimplemented:
    // If you ever implement these, use rwAtomicExchange to copy the classes
    CReference(const CReference&);
    CReference& operator=(const CReference&);
};



分享到:
评论
3 楼 sogo6 2011-10-29  
class TTestImpl : public CReference
{
public:
    TTestImpl()
    {
        m_buffer = new char[1024];
        memset(m_buffer, 0x0, 1024);
    }
    ~TTestImpl()
    {
        if (NULL != m_buffer)
        {
            delete m_buffer;
            m_buffer = NULL;
        }
    }

    void Func()
    {
        printf("Hello Tiky.....");
    }

private:
    char *m_buffer;
};

class TTest
{
public:
    TTest(){}

    ~TTest(){}

    void Func()
    {
        m_impl->Func();
    }
private:
    CCountedRef<TTestImpl> m_impl;
};

int main(int argc, char *argv[])
{
    TTest myTest;
    
    {
        TTest myTest1 = myTest;
        myTest1.Func();
    }
    myTest.Func();

    return 0;
}
2 楼 sogo6 2011-10-29  
template<class T> 
class  CMTCountedRef
{
    typedef  ACE_Thread_Mutex    CMTCRefMutexType;
public:
    // We didn't assign NULL for initialization to avoid threading problems
    CMTCountedRef(T* impl)
    {
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        if(impl) 
        {
            T_STATIC_CAST(CReference*, impl)->addReference();
        }
        impl_ = impl;
    }

    // We didn't assign NULL for initialization to avoid threading problems
    CMTCountedRef(const CMTCountedRef<T>& ref)
    {
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex>guard(m_mtx);
        if(ref.impl_) 
        {
            T_STATIC_CAST(CReference*, ref.impl_)->addReference();
        }
        impl_ = ref.impl_;
    } 
    virtual ~CMTCountedRef()
    {
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex()); 
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        detach();
    }
    CMTCountedRef<T>& operator=(const CMTCountedRef<T>& rhs)
    {
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        if(rhs.impl_) RWDBSTATIC_CAST(CReference*, 
            rhs.impl_)->addReference();
        detach();
        impl_ = rhs.impl_;
        return *this;
    }
    CMTCountedRef<T>& operator=(T* impl)
    {
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        if(impl) RWDBSTATIC_CAST(CReference*, impl)->addReference();
        detach();
        impl_ = impl;
        return *this;
    }
    operator T*() const { 
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        return impl_; 
    }
    T* operator->() const { 
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        //assert(impl_);
        return impl_; 
    }
    T& operator*() const {
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        //assert(impl_);
        return *impl_;
    }
    bool operator==(const CMTCountedRef<T>& rhs) const {
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        return ( impl_ && ( impl_ == rhs.impl_ ) );
    }
    bool operator!=(const CMTCountedRef<T>& rhs) const {
        //RWDBGUARD2(RWDBMTCRefMutexType, levelIIMutex());
        ACE_Guard<ACE_Thread_Mutex> guard(m_mtx);
        return ! ( impl_ && ( impl_ == rhs.impl_ ) );
    }
protected:
   
    void detach()
    {
        //No need for the MT Guard, because we are already heavily
        //  guarded against concurrent access.
        if(impl_ && T_STATIC_CAST(CReference*, impl_)->removeReference() < 1)
        {
            //If the following line fails then:
            // (1) It was already deleted?
            // (2) The object was created on the stack 
            //delete RWDBREINTERPRET_CAST(RWDBReference*, impl_);
            delete REINTERPRET_CAST(RWDBReference*, impl_);
            impl_ = NULL;
        }
    }
    CMTCRefMutexType m_mtx;
private:
    T* impl_;
};
1 楼 sogo6 2011-10-29  
template<class T> 
class  CCountedRef
{
public:
    CCountedRef()
    {
        impl_ = new T;
    }
    CCountedRef(T* impl)
        : impl_(impl)
    {
        if(impl_) {
            T_STATIC_CAST(CReference*, impl_)->addReference();
        }
    }

    CCountedRef(const CCountedRef<T>& ref)
        :impl_(ref.impl_) // Always assign, even if NULL
    {   
        if(ref.impl_) 
        {
            //T_STATIC_CAST(CReference*, ref.impl_)->addReference();
        }
    }

    ~CCountedRef()
    {
        detach();
    }

    CCountedRef<T>& operator=(const CCountedRef<T>& rhs)
    {
        if(rhs.impl_) {
            T_STATIC_CAST(CReference*, rhs.impl_)->addReference();
        }
        detach();
        impl_ = rhs.impl_;
        return *this;
    }

    CCountedRef<T>& operator=(T* impl)
    {
        if(impl) {
            T_STATIC_CAST(CReference*, impl)->addReference();
        }
        detach();
        impl_ = impl;
        return *this;
    }

    operator T*() const { 
        return impl_; 
    }

    T* operator->() const { 
        //assert(impl_);
        return impl_; 
    }

    T& operator*() const {
        //assert(impl_);
        return *impl_;
    }

    bool operator==(const CCountedRef<T>& rhs) const {
        return (impl_ && (impl_ == rhs.impl_));
    }
    bool operator!=(const CCountedRef<T>& rhs) const {
        return !(impl_ && (impl_ == rhs.impl_));
    }
protected:
    void detach() {
        if(impl_ && T_STATIC_CAST(CReference*, impl_)->removeReference() < 1) 
        {
            //If the following line fails when:
            // (1) It was already deleted?
            // (2) The object was created on the stack 
            delete T_STATIC_CAST(CReference*, impl_);
            impl_ = NULL;
        }
    }
    T* impl_;
};

相关推荐

    引用计数的c++源码实现

    在这个项目中,使用了模板来实现引用计数,模板是一种强大的工具,可以让我们编写泛化的代码,适用于多种类型。模板允许我们创建类或函数,而不指定具体的类型。这意味着我们可以创建一个通用的引用计数器,可以用于...

    COM-引用计数

    引用计数是COM实现对象生命周期管理的关键机制,尤其在内存管理方面起到重要作用。 引用计数的基本原理是,每当一个客户端(如另一个对象或程序)获得对COM对象的引用时,该对象的引用计数就会增加1;当客户端不再...

    smartptr——基于自动引用计数的智能指针

    智能指针相信大家听说过吧,我理解的智能指针,既是一个C++模板类,重载了指针操作符(-&gt;)和(*)操作符,而使它的实例可以"用指针的形式...可以实现任意类型(基本数据类型、自定义类型)的指针地址的自动引用计数。

    模板和智能指针(c++)

    它通过引用计数来跟踪有多少个`shared_ptr`在使用该对象。 3. `std::weak_ptr`:这种智能指针不增加对象的引用计数,主要用于解决循环引用问题。它可以观察一个对象,但不会防止对象被删除。当试图访问`weak_ptr`...

    C++ 模板树 ltree_1.0

    `shared_ptr`使用引用计数来决定何时释放对象,它可以防止资源泄露并简化内存管理。如果编译环境中不支持`std::tr1::shared_ptr`,开发者可以选择使用普通指针,但需要手动管理内存,这会增加程序出错的可能性。 ...

    办公常用excel表格模板,免费excel表格模板大全,办公室常用的excel函数

    3. **公式引用**:使用相对引用、绝对引用和混合引用,使公式随单元格位置变化而调整或固定。 4. **冻结窗口**:在滚动查看大表时,保持某些行或列始终可见。 5. **数据验证**:限制单元格输入的数据类型或范围,...

    【LaTeX模板】作业文档

    6. **引用和参考文献**:如果作业需要引用文献,LaTeX提供了方便的引用系统,如`\cite`命令,可与BibTeX结合使用,管理参考文献。 7. **图形和表格**:模板支持插入和排版图形及表格,使得数据呈现更为直观。 8. *...

    C++智能指针.pdf

    综上所述,智能指针是C++中一种重要的内存管理工具,它通过引用计数确保对象在不再使用时自动释放,大大提高了代码的健壮性和安全性。OpenCV的`Ptr`模板类则为处理OpenCV库内的对象提供了类似的便利。在实际编程中,...

    “华为杯”中国研究生数学建模竞赛latex模板.zip

    同时,为了描述机器学习模型,可能会使用`booktabs`创建专业表格,`siunitx`规范科学计数法的表示。 总的来说,"华为杯"中国研究生数学建模竞赛的LaTeX模板提供了标准化的框架,方便参赛者专注于模型构建和报告撰写...

    C++ 智能指针实现

    引用计数智能指针是智能指针的一种实现方式,其核心思想是为每个被管理的对象维护一个引用计数器。每当一个新的智能指针指向该对象时,引用计数增加;当智能指针超出作用域或被显式销毁时,引用计数减少。当引用计数...

    智能指针的介绍和用法

    CRefPtr是一个智能指针类模板,它封装了对CReferenced派生类的引用计数管理。使用CRefPtr时,程序员通常不需要直接操作引用计数,因为CRefPtr内部会自动处理。CRefPtr的实例在使用完毕后,当引用计数降至零时,它所...

    SmartPointer:C ++中的SmartPointer实现。 SmartPointer是一种通过模板实现的数据类型,它可以模拟指针,同时还提供自动垃圾回收

    SmartPointer可以使用泛型/模板指向任何类型的对象SmartPointer通过自动内存管理提供安全性避免指针悬空,内存泄漏和分配失败之类的问题SmartPointer必须维护对给定对象的所有引用的单个引用计数

    Qt源码剖析-智能指针.pdf

    这样设计是为了实现引用计数,确保只有当没有其他QSharedPointer实例存在时才释放内存。 QSharedPointer的实现原理是通过引用计数来跟踪对象的生命周期。每当创建一个新的QSharedPointer实例,都会增加引用计数;当...

    loki库模板元编程的经典库

    - `SharedPtr`:提供了引用计数功能,类似于`std::shared_ptr`,允许多个指针共享同一对象。 2. **Singleton**: - 提供了`Singleton`模板,实现了单例模式,确保类只有一个实例,并提供全局访问点。 3. **...

    MFC实现简单的COM

    每次释放或对象不再使用时,引用计数减一,当计数为零时自动销毁对象。 7. **接口的晚绑定和早绑定**: - **晚绑定(Late Binding)**:通过IDispatch接口实现,适用于不预先知道接口的具体类型的情况,如VBA脚本...

    Android_WP_SP浅析

    它们都是基于类RefBase的引用计数机制来实现的,旨在自动管理对象生命周期,减轻开发者手动管理内存的负担。 1. **类RefBase**: RefBase是所有需要智能指针管理的对象的基础类。它维护了一个内部的引用计数,用于...

    C++智能指针shared-ptr讲解与使用.pdf

    为了检查`shared_ptr`的引用计数,可以使用`use_count()`成员函数: ```cpp std::cout () ; ``` 这会打印出当前`ptr1`的引用计数。 另外,`shared_ptr`还可以与其他辅助类一起使用,如`weak_ptr`用于解决循环引用...

    详解Django项目中模板标签及模板的继承与引用(网站中快速布置广告)

    ### Django项目中模板标签及模板的继承与引用详解 #### 一、引言 Django 是一款用 Python 编写的开源框架,它以其强大的功能、灵活性以及高效的开发速度深受开发者们的喜爱。在 Django 中,模板系统是其核心组成...

    UE4智能指针Demo代码.zip

    TSharedPtr是UE4中的共享智能指针类型,它实现了引用计数的特性。当你创建一个TSharedPtr实例时,对象的引用计数会增加。当最后一个TSharedPtr释放时,对象会被自动销毁。`MyActor.cpp`和`MyActor.h`文件中可能会...

Global site tag (gtag.js) - Google Analytics