晓寒的小屋

随笔分类

随笔档案

相册

最新评论

阅读排行榜

评论排行榜

程序员博客   首页  新随笔  订阅  管理  登录 
 
晓寒 阅读(1170) 评论(10)
/**
*  @file     CHSmartPointer.h
*  @class    CHSmartPointer
*  @author   flyingleaf
*  @version  1.0.0.0
*  @date     2006-07-26
*  @brief    您可以任使用此文件,但是需要保留本声明
*/


#ifndef _XHJ_CHSmartPointer_h
#define _XHJ_CHSmartPointer_h

#include 
<iostream>

namespace XHJ
{
    
/**
    * @class CHSmartPointer
    
*/

    template 
<class TObjectType>
    
class CHSmartPointer 
    
{
    
public:
        typedef TObjectType ObjectType;

        
/** 构造函数 */
        CHSmartPointer () 
        

            m_Pointer 
= NULL;
        }


        
/**拷贝构造函数 */
        CHSmartPointer (
const CHSmartPointer<ObjectType>& p):m_Pointer(p.m_Pointer)
        

            
this->Register();
        }


        
/** 以原始指针为参数的构造函数  */
        CHSmartPointer (ObjectType 
*p):    m_Pointer(p)
        

            
this->Register();
        }
                             

        
/** 析构函数 */
        
~CHSmartPointer ()
        
{
            
this->UnRegister();
            m_Pointer 
= NULL;  
        }


        
void Destroy()
        
{
            
this->UnRegister();
            m_Pointer 
= NULL;  
        }



        
/** 重载运算符 '->' */
        ObjectType
* operator -> () const
        
{
            
return m_Pointer; 
        }


        
/** 重载运算符 '* ' */
        ObjectType
& operator *() const
        
{
            
return *m_Pointer;
        }



        
        
/**
        *  与继承有关的类型转换.
        
*/

        template
<class newType>    operator CHSmartPointer<newType>()
        
{
            
return CHSmartPointer<newType>(m_Pointer);
        }
  

        
/** 检测原始指针是否已经初始化 */
        
bool IsNull() const
        
{
            
return m_Pointer == NULL;
        }


        
bool IsNotNull() const
        
{
            
return m_Pointer != NULL;
        }


        
/** 模板化的指针比较 重载运算符'==' 和'!='  */
        template 
<typename R>    bool operator == ( R r ) const
        

            
return (m_Pointer == (ObjectType*)(r.m_Pointer) ); 
        }


        template 
<typename R>    bool operator != ( R r ) const
        

            
return (m_Pointer != (ObjectType*)(r.m_Pointer) ); 
        }


        
/** 指针获取函数 */
        ObjectType 
*GetPointer () const 
        

            
return m_Pointer; 
        }


        
/** 指针比较。小于  */
        
bool operator < (const CHSmartPointer &r) const
        

            
return (void*)m_Pointer < (void*) r.m_Pointer; 
        }


        
/** 指针比较。大于 */
        
bool operator > (const CHSmartPointer &r) const
        

            
return (void*)m_Pointer > (void*) r.m_Pointer; 
        }


        
/** 指针比较。小于等于 */
        
bool operator <= (const CHSmartPointer &r) const
        

            
return (void*)m_Pointer <= (void*) r.m_Pointer; 
        }


        
/** 指针比较。大于等于 */
        
bool operator >= (const CHSmartPointer &r) const
        
{
            
return (void*)m_Pointer >= (void*) r.m_Pointer; 
        }


        
/** 赋值重载 */
        CHSmartPointer 
&operator = (const CHSmartPointer &r)
        
{
            
return this->operator = (r.GetPointer()); 
        }


        
/** 赋值重载 */        
        CHSmartPointer 
&operator = (ObjectType *r)
        
{                                                              
            
if (m_Pointer != r)
            
{
                
//先注销当前的。
                if ( m_Pointer )
                

                    m_Pointer
->UnRegister(); 
                }


                
//指向现在的,并且注册
                m_Pointer = r;
                
this->Register();
                
            }

            
return *this;
        }


    
private:
        
/** 智能指针指向的原始指针. */
        ObjectType
* m_Pointer;

        
void Register()
        

            
if(m_Pointer) { m_Pointer->Register(); }
        }


        
void UnRegister()
        
{
            
if(m_Pointer) { m_Pointer->UnRegister(); }
        }

    }
;  
}
 // end namespace UT

#endif
呵呵,不过如果想使用,需要从我下边的这个类派生。哈哈
CHObject
/**
*  @file     CHSmartPointer.h
*  @class    CHSmartPointer
*  @author   flyingleaf
*  @version  1.0.0.0
*  @date     2006-07-26
*  @brief    您可以任使用此文件,但是需要保留本声明
*/


#ifndef _XHJ_CHObject_h
#define _XHJ_CHObject_h

#include 
<string>
#include 
<iostream>
#include 
<typeinfo.h>
#include 
<CHMutex.h>
#include 
<CHSmartPointer.h>

/** 对象创建宏   */
#define CHNewMacro(type) \
static Pointer New(void) \
{ \
    type 
*rawPtr = new type; \
    Pointer smartPtr 
= rawPtr; \
    
return smartPtr; \
}
 

/** 从CHObject派生出来的类的固定格式宏   */
#define CHObjectDefine(type) \
typedef type     Self;      \
typedef CHSmartPointer
<Self>  Pointer;\
typedef CHSmartPointer
<const Self>  ConstPointer;\
CHNewMacro(Self);

namespace XHJ
{
    
/**  @class    CHObject */
    
class CHObject : public CHMutex
    
{
        
public:
            
/** 统一typedef定义 */
            CHObjectDefine(CHObject);

            
/** 以字符串形式返回类名。可用来支持RTTI或者进行调试信息输出 */
            
static  std::string GetNameOfClass() 
            
{
                
return "CHObject";
            }
            

            
/**引用计数方式下的对象销毁方法.*/
            
void Delete(); 

            
/** 当本对象被其他对象引用时,增加引用计数.*/
            
void Register() ;

            
/** 其他对象不在引用本对象时,减少引用计数。*/
            
void UnRegister() ;

            
/** 返回引用计数.*/
            
int GetReferenceCount() const 
            
{
                
return m_ReferenceCount;
            }


           
       
protected:       
            
/** 缺省构造函数。 起始引用计数为0。*/
            CHObject():m_ReferenceCount(
0){};

            
/** 析构函数。*/
            
virtual ~CHObject(); 
   
            
/** 引用计数 */
            
int m_ReferenceCount;

        
private:
            
/** 拒绝拷贝构造。*/
            CHObject(
const Self&); 

            
/** 拒绝赋值 */
            
void operator=(const Self&); 
    }
;
}
 
  
#endif

CHObject.cpp
#include "stdafx.h"
#include 
<CHObject.h>
#include 
<list>
#include 
<iostream>
#include 
<memory>
#include 
<CHException.h>

namespace XHJ
{
    
void CHObject::Delete() 
    
{
        
this->UnRegister();
    }



    
/** 当本对象被其他对象引用时,增加引用计数. */
    
void  CHObject::Register() 
    
{
        Lock 
lock(*this);
        m_ReferenceCount
++;
    }



    
/** 其他对象不在引用本对象时,减少引用计数. */
    
void CHObject::UnRegister() 
    
{    
        
bool bNeedDel = false;

        
//这里delete this的时候需要小心不要使用Lock,否则.嘿嘿
        {
            Lock 
lock(*this);
            m_ReferenceCount
--;
            
if ( m_ReferenceCount <= 0
                bNeedDel 
= true;
        }


        
if ( bNeedDel )
        
{
            delete 
this;
        }

    }



    CHObject::
~CHObject() 
    
{
        
if ( m_ReferenceCount > 0)
        
{
            
throw CHUserException(__FILE__, __LINE__,  "试图删除一个引用计数不为零的对象");
        }

    }


}
 


使用如下:
/**
*  @file     CHTestObject.h
*  @class    CHTestObject
*  @author   flyingleaf
*  @version  1.0.0.0
*  @date     2005-04-07
*  @brief    您可以任使用此文件,但是需要保留本声明
*/


#include 
<CHObject.h>

namespace XHJ
{
    
class CHTestObject : public CHObject
    
{
    
public:
        CHObjectDefine(CHTestObject);

        
const char* Name() return "test";}

    
protected:
        CHTestObject(
void){};
        
~CHTestObject(void){};
    }
;
}


void Test()
{
        CHTestObject::Pointer p;
    p 
= CHTestObject::New();
    
    CHTestObject::Pointer p2 
= p;
    cout 
<< p->Name() << "  " << p2->Name() << p2->GetNameOfClass();
}

评论列表
hpho
re: 基础库___智能指针
1, 两个宏都少了继行符'\'
2, CHSmartPointer<const Self>会使得
    CHSmartPointer::m_Pointer;是const的但
   明显Self::Register()和Self::UnRegister()都不是
   const修饰的, 那么CHSmartPointer::Register()和
   CHSmartPointer::UnRegister()不会错吗??
3, CHObject::GetNameOfClass()竟然是static的?
   那
    class D: public CHObject;
   CHObject pBase=new D();
   pBase->GetNameOfClass();//怎样也表现不出RIIT.
4,
    CHTestObject test;
    CHTestObject::Pointer p;
    p=&test;
    这样怎解决:-P  
晓寒
3ks hpho 的热情。
1、有序行符的,但是网页不知道为何没有表达出来。
2、又两个,一个是常量的一个不是。
typedef CHSmartPointer<Self> Pointer;
typedef CHSmartPointer<const Self> ConstPointer;
3、 直接使用new是不可以的。因为我必须要求所有的派生内都是用宏: CHObjectDefine(type),这样如果需要实例化像我提供的例子那样:
CHTestObject::Pointer p;
p = CHTestObject::New();
4、我。。。。我没有想到这个样子的。呵呵。我回头想想。
hpho
re: 基础库___智能指针
第二点你还没明白我在说什么.
看看这个化简的CODE吧
template <class TObjectType>
class CHSmartPointer {
private:
        /**//** 智能指针指向的原始指针. */
    TObjectType* m_Pointer;
    
public:
void UnRegister()
{
    if(m_Pointer) { m_Pointer->UnRegister(); }
}
};

class CHObject{
public:
typedef CHSmartPointer<const CHObject>  ConstPointer;
void CHObject::UnRegister(){}
// 这个是void CHObject::UnRegister()const!!
};

int main()
{
CHObject::ConstPointer p;
p.UnRegister(); // error!!
//因为m_Pointer是const CHObject*
  return 0;
}
晓寒
_-_!
收到。 我暂时没有好主意了。 能否提个修改建议。总不至于不支持常量指针吧?_-_!
hpho
re: 基础库___智能指针
方法是这样的:
1, 要把Object里引用部分抽出来, 假设此class定义为:
   class RefCnt{
       int count;
       Object* obj;
    public:
       RefCnt(Object* po):obj(po){}
       unreg(){...; delete obj;}
   };

2, Object则为:
   class Object{
       RefCnt* pRefC;
   public:
       Object(){
          pRefC=new RefCnt(this);
       }

       ~Object(){delete pRefC;}
   };

因为就算是const Object, pRefC也只是RefCnt* const, 所以就避开了Object的const. 还有就是这里的delete并不会引起递归!

现在的智能指针Point的operator()->就可以用RefCnt里的Object*, 问题是你怎样把Point和RefCnt建立关系!? 这里你自己想吧. (要注意RefCnt成员函数的访问权限应该只给Point哦, 这里可能要用友员!)

----------------------------
我发现你原来的CHObject::UnRegister();这些都是公有的. 那么
   CHTestObject::Pointer p;
    p = CHTestObject::New();
   for(int i=0; i<10; ++i)
      p->Register();
   随便地修改了引用个数!


fastzhao
re: 基础库___智能指针
我觉得你不用哪个CHObject类了,那个类就实现了一个引用记数,而且迫使用户的类必须从你这个类继承,才能建立smartpointer类。

我认为应该把引用记数放在smartpointer类中。

下面的代码是我模仿<c++沉思录>中的实现一个smartpointer:

#ifndef _SHAREPRT_H_
#define _SHAREPRT_H_

template<typename T>
class SharePtr;

template<typename T>
bool operator< (const SharePtr<T>& Lop,const SharePtr<T>& Rop);

template<typename T>
bool operator== (const SharePtr<T>& Lop,const SharePtr<T>& Rop);


template<typename T>
class SharePtr
{
friend bool operator< <T> (const SharePtr& Lop, const SharePtr& Rop);
friend bool operator== <T> (const SharePtr& Lop,const SharePtr& Rop);
T* pSurrogateObj; //代理的类
int* useCount;    //引用记数,这里用指针是因为所有的代理类只有一个引用记数
CRITICAL_SECTION* m_lockSharePtr;
public:
//int getCount(){return *useCount;}
SharePtr(T* pObj = NULL): useCount(new int(1)), pSurrogateObj(pObj)
{
//TRACE("useCount create:%d\n", *useCount);
m_lockSharePtr = new CRITICAL_SECTION;
InitializeCriticalSection(m_lockSharePtr);
}
~SharePtr(void)
{
EnterCriticalSection(m_lockSharePtr);
//TRACE("useCount realese:%d\n", *useCount);
if(--(*useCount) == 0)
{
delete useCount;
delete pSurrogateObj;
LeaveCriticalSection(m_lockSharePtr);
DeleteCriticalSection(m_lockSharePtr);
delete m_lockSharePtr;
//TRACE("User Conn close!\n");
}
else
{
LeaveCriticalSection(m_lockSharePtr);
}

}
SharePtr(const SharePtr& ref): useCount(ref.useCount), pSurrogateObj(ref.pSurrogateObj) 
{
m_lockSharePtr = ref.m_lockSharePtr;
EnterCriticalSection(m_lockSharePtr);
if(pSurrogateObj != NULL)
{
++(*useCount);
//TRACE("useCount copy constuct: %d\n", *useCount);
}
LeaveCriticalSection(m_lockSharePtr);
}

SharePtr& operator= (const SharePtr& ref)
{
EnterCriticalSection(m_lockSharePtr);
if(this != &ref) 
{
if(--(*useCount) == 0)
{
delete useCount;
delete pSurrogateObj;
}
useCount = ref.useCount;
pSurrogateObj = ref.pSurrogateObj;
if(pSurrogateObj != NULL)
++(*useCount);
//TRACE("useCount operator==: %d\n", *useCount);
}
LeaveCriticalSection(m_lockSharePtr);
return *this;
}

T& operator*()
{
return *pSurrogateObj;
}

T* operator->()
{
return pSurrogateObj;
}

T* RealPiont()
{
return pSurrogateObj;
}

bool IsNull()
{
return (pSurrogateObj == NULL);
}
/*void ReplaceObj(const SharePtr& ref)
{
//delete pSurrogateObj;
pSurrogateObj = ref.pSurrogateObj;
}*/
};

template<typename T>
bool operator< (const SharePtr<T>& Lop, const SharePtr<T>& Rop) 
{
return (*Lop.pSurrogateObj < *Rop.pSurrogateObj);
}

template<typename T>
bool operator== (const SharePtr<T>& Lop, const SharePtr<T>& Rop)
{
return (*Lop.pSurrogateObj == *Rop.pSurrogateObj);
}
#endif
Zhuyie
re: 基础库___智能指针
限制太死,boost中的智能指针类很好用。

发表评论
切换编辑模式