游戏开发论坛

 找回密码
 立即注册
搜索
查看: 9229|回复: 12

求助:如何编写模版类支持NULL==obj的operator

[复制链接]

25

主题

304

帖子

311

积分

中级会员

Rank: 3Rank: 3

积分
311
发表于 2006-12-8 09:42:00 | 显示全部楼层 |阅读模式
我这样写,不行。。。。。

template<class T>
inline bool operator ==( T * p,   CObjClass<T> & obj )
{
.......
}

出现如下错误
error C2678: 二进制“==” : 没有找到接受“int”类型的左操作数的运算符(或没有可接受的转换)

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2006-12-8 10:08:00 | 显示全部楼层

Re:求助:如何编写模版类支持NULL==obj的operator

没可能

8

主题

716

帖子

716

积分

高级会员

Rank: 4

积分
716
发表于 2006-12-8 10:55:00 | 显示全部楼层

Re:求助:如何编写模版类支持NULL==obj的operator

1. 安全的方法: CObjClass提供.get返回T*,则这里应该是if (NULL == obj.get())
2. 方便的方法: CObjClass提供operator T*,则if (NULL == obj)成立

template <typename T>
class Object
{
        T        _inst;

public:
        operator T const* ()const
        {
                return &_inst;
        }
};

template<class T>
inline bool operator == ( T const* p, Object<T> const& obj )
{
        // both null pointer
        if (obj == 0 || p == 0)
        {
                return false;
        }
        else
        {
                return obj == p;
        }
}

int _tmain(int argc, _TCHAR* argv[])
{
        Object<int> nObj;
        int x;
        if (nObj == &x)
        {
        }

        return 0;
}

方法2有一个好处是,一旦提供opeator T*,则不论是(nObj == &x)或是if (&x == nObj)都可成立,甚至operator ==也失去了存在的意义;而方法1不行,但是安全,试问为什么std::string没有operator char *而是提供c_str即是这个原因。

25

主题

304

帖子

311

积分

中级会员

Rank: 3Rank: 3

积分
311
 楼主| 发表于 2006-12-8 12:35:00 | 显示全部楼层

Re:求助:如何编写模版类支持NULL==obj的operator

string没有提供operator char *是因为char operator [] 会和c++给char*的 char operator []() 发生冲突

opeartor T *仍然不能进行NULL的转换,因为NULL是个int
我现在用的是int做首参数来专门对付NULL,其他的指针比较,使用operator T*
算是解决了,可是总是有点让人莫名其妙的感觉。

8

主题

716

帖子

716

积分

高级会员

Rank: 4

积分
716
发表于 2006-12-8 12:51:00 | 显示全部楼层

Re:求助:如何编写模版类支持NULL==obj的operator

提供operator T* 后在vs2005上是通过的
LZ的信息提供太少

对于object == NULL这种,compiler会有一个匹配顺序
当找不到显式的调用时,c++ compiler会进行隐式转换,通过ctor和operator
首先是试着用NULL来构造一个CObjClass,失败后会继续寻找合适的operator

但有时这并不是我们所希望见到的
如果是constructor还可以通过explicit来屏蔽
但是operator type就挡不住了
所以这才是std::string不直接提供operator char *的原因
另外,std::string的不同实现也是因素之一

25

主题

304

帖子

311

积分

中级会员

Rank: 3Rank: 3

积分
311
 楼主| 发表于 2006-12-8 16:51:00 | 显示全部楼层

Re:求助:如何编写模版类支持NULL==obj的operator

2005分辩不出
(operator char *)[]

operator []
的区别,所以,string没办法同时实现两个,
编译可以通过,但是某些使用[]的场合就会出问题。
以前给朋友编译的一个工程里的string就同时使用了这两个,结果在2005下不通过。

string的==和operator char*的冲突也是因素之一。所以不能使用operator char*

25

主题

304

帖子

311

积分

中级会员

Rank: 3Rank: 3

积分
311
 楼主| 发表于 2006-12-8 16:57:00 | 显示全部楼层

Re:求助:如何编写模版类支持NULL==obj的operator

这个是我的代码,我希望实现
xObjectRef<Type> obj;
if( NULL == obj )
{
}


==========================代码=========================
template <class TClass>
class xObjectRef
{
        typedef struct tagObjectRef
        {
                int                nRefCount;
                TClass*        pObject;
                BYTE        ObjMem[sizeof(TClass)+(4-sizeof(TClass)&3)];
        }ObjectRef;
        static xObjectPoolEx_T<ObjectRef> m_xObjectRefPool;
public:
        xObjectRef() : m_pObjectRef(NULL)
        {
        }

        xObjectRef( xObjectRef<TClass> & objref ) : m_pObjectRef(objref.m_pObjectRef)
        {
                if( this->m_pObjectRef != NULL )
                        this->m_pObjectRef->nRefCount++;
        }

        explicit xObjectRef( TClass * pObject ) : m_pObjectRef(NULL)
        {
                if( pObject != NULL )
                {
                        ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                        if( pRef )
                        {
                                pRef->pObject = pObject;
                                this->m_pObjectRef = pRef;
                                pRef->nRefCount++;
                        }
                }
        }

        virtual ~xObjectRef()
        {
                Free();
        }

        xObjectRef<TClass> & Create()
        {
                ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                if( pRef )
                {
                        pRef->pObject = (TClass*)m_pObjectRef->ObjMem;
                        CALL_CON( pRef->pObject );        //        创建Object
                        Free();
                        this->m_pObjectRef = pRef;
                        pRef->nRefCount++;
                }
                return (*this);
        }

        template <class Tp1>
        xObjectRef<TClass> & Create( Tp1 p1 )
        {
                ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                if( pRef )
                {
                        pRef->pObject = (TClass*)m_pObjectRef->ObjMem;
                        CALL_CON( pRef->pObject, p1 );        //        创建Object
                        Free();
                        this->m_pObjectRef = pRef;
                        pRef->nRefCount++;
                }
                return (*this);
        }

        template <class Tp1, class Tp2>
        xObjectRef<TClass> & Create( Tp1 p1, Tp2 p2 )
        {
                ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                if( pRef )
                {
                        pRef->pObject = (TClass*)m_pObjectRef->ObjMem;
                        CALL_CON( pRef->pObject, p1, p2 );        //        创建Object
                        Free();
                        this->m_pObjectRef = pRef;
                        pRef->nRefCount++;
                }
                return (*this);
        }

        template <class Tp1, class Tp2, class Tp3>
        xObjectRef<TClass> & Create( Tp1 p1, Tp2 p2, Tp3 p3 )
        {
                ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                if( pRef )
                {
                        pRef->pObject = (TClass*)m_pObjectRef->ObjMem;
                        CALL_CON( pRef->pObject, p1, p2, p3 );        //        创建Object
                        Free();
                        this->m_pObjectRef = pRef;
                        pRef->nRefCount++;
                }
                return (*this);
        }

        template <class Tp1, class Tp2, class Tp3, class Tp4>
        xObjectRef<TClass> & Create( Tp1 p1, Tp2 p2, Tp3 p3, Tp4 p4 )
        {
                ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                if( pRef )
                {
                        pRef->pObject = (TClass*)m_pObjectRef->ObjMem;
                        CALL_CON( pRef->pObject, p1, p2, p3, p4 );        //        创建Object
                        Free();
                        this->m_pObjectRef = pRef;
                        pRef->nRefCount++;
                }
                return (*this);
        }

        template <class Tp1, class Tp2, class Tp3, class Tp4, class Tp5>
        xObjectRef<TClass> & Create( Tp1 p1, Tp2 p2, Tp3 p3, Tp4 p4, Tp5 p5 )
        {
                ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                if( pRef )
                {
                        pRef->pObject = (TClass*)m_pObjectRef->ObjMem;
                        CALL_CON( pRef->pObject, p1, p2, p3, p4, p5 );        //        创建Object
                        Free();
                        this->m_pObjectRef = pRef;
                        pRef->nRefCount++;
                }
                return (*this);
        }

        template <class Tp1, class Tp2, class Tp3, class Tp4, class Tp5, class Tp6>
        xObjectRef<TClass> & Create( Tp1 p1, Tp2 p2, Tp3 p3, Tp4 p4, Tp5 p5, Tp6 p6 )
        {
                ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                if( pRef )
                {
                        pRef->pObject = (TClass*)m_pObjectRef->ObjMem;
                        CALL_CON( pRef->pObject, p1, p2, p3, p4, p5, p6 );        //        创建Object
                        Free();
                        this->m_pObjectRef = pRef;
                        pRef->nRefCount++;
                }
                return (*this);
        }

        template <class Tp1, class Tp2, class Tp3, class Tp4, class Tp5, class Tp6, class Tp7>
        xObjectRef<TClass> & Create( Tp1 p1, Tp2 p2, Tp3 p3, Tp4 p4, Tp5 p5, Tp6 p6, Tp7 p7 )
        {
                ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                if( pRef )
                {
                        pRef->pObject = (TClass*)m_pObjectRef->ObjMem;
                        CALL_CON( pRef->pObject, p1, p2, p3, p4, p5, p6, p7 );        //        创建Object
                        Free();
                        this->m_pObjectRef = pRef;
                        pRef->nRefCount++;
                }
                return (*this);
        }

        VOID Free()
        {
                if( m_pObjectRef != NULL )
                {
                        m_pObjectRef->nRefCount--;
                        if( m_pObjectRef->nRefCount <= 0 )
                        {
                                TClass * pObj = (TClass*)m_pObjectRef->ObjMem;
                                CALL_DEC( pObj );        //        销毁Object
                                m_xObjectRefPool.deleteObject( m_pObjectRef );
                        }
                        m_pObjectRef = NULL;
                }
        }

        xObjectRef<TClass> & operator =( xObjectRef<TClass> & objref )
        {
                Free();
                m_pObjectRef = objref.m_pObjectRef;
                if( m_pObjectRef )
                {
                        m_pObjectRef->nRefCount++;
                }
                return (*this);
        }

        xObjectRef<TClass> & operator =( TClass * pObject )
        {
                if( pObject != NULL )
                {
                        ObjectRef * pRef = this->m_xObjectRefPool.newObject();
                        if( pRef )
                        {
                                pRef->pObject = pObject;
                                Free();
                                this->m_pObjectRef = pRef;
                                pRef->nRefCount++;
                        }
                }
        }

        bool operator ==( const xObjectRef<TClass> & objref ) const
        {
                return (m_pObjectRef == objref.m_pObjectRef );
        }

        bool operator ==( TClass * pObject ) const
        {
                if( m_pObjectRef == NULL )
                {
                        return (pObject==NULL);
                }
                return ((TClass*)m_pObjectRef->ObjMem == pObject );
        }

        bool operator !=( const xObjectRef<TClass> & objref ) const
        {
                return (m_pObjectRef != objref.m_pObjectRef );
        }

        bool operator !=( TClass * pObject ) const
        {
                if( m_pObjectRef == NULL )
                {
                        return (pObject!=NULL);
                }
                return ((TClass*)m_pObjectRef->ObjMem == pObject );
        }

        (operator TClass*)()const{ return (TClass*)m_pObjectRef->ObjMem;}
        (operator TClass&)()const{ return *(TClass*)m_pObjectRef->ObjMem;}

        TClass * operator->()const{ return (TClass*)m_pObjectRef->ObjMem;}
        TClass & operator*()const{ return *(TClass*)m_pObjectRef->ObjMem;}
protected:
        ObjectRef * m_pObjectRef;
};

template <class TClass>
xObjectPoolEx_T<typename xObjectRef<TClass>::ObjectRef> xObjectRef<TClass>::m_xObjectRefPool;



//        for NULL == *this
template <class TClass>
inline bool operator ==( const int pObject, const xObjectRef<TClass> & ref )
{
        return (ref == (TClass*)pObject);
}

3

主题

16

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2006-12-8 21:28:00 | 显示全部楼层

Re: Re:求助:如何编写模版类支持NULL==obj的operator

谜の名侦探: Re:求助:如何编写模版类支持NULL==obj的operator

opeartor T *仍然不能进行NULL的转换,因为NULL是个int
我现在用的是int做首参数来专门对付NULL,其他的指针比较,使用operator T*
算是解决了,可是总是有点让人莫名其妙的感觉。


提供operator T *()的话,进行(NULL == obj)比较时是将NULL和obj都转
换成T *再比较的,所以这个解决方法是可以的,只不过使用起来不太安全。

或者实现下面的全局操作符,和上边效果差不多,不过也不太安全:
template <class T>
inline bool operator ==(const void * const p, const CObjClass<T> &obj);

或者用operator !()来替代判断(NULL == obj)。

8

主题

716

帖子

716

积分

高级会员

Rank: 4

积分
716
发表于 2006-12-11 11:19:00 | 显示全部楼层

Re:求助:如何编写模版类支持NULL==obj的operator

周末没网

我说的是operator char* (),而LZ说的是operator char *[],一个圆来一个方,咱们是马嘴不对驴唇
上面我指的是大家需要思考为什么standard c plus plus为什么不给std::string提供operator const char*()让它用起来更像POD指针,却只通过c_str()来操作的原因


因为NULL == 0, 所以当提供opeator T*后是绝对可以通过编译的
LZ还是没有提供compiler的型号,同上所述,我的vs2005是通过的
anyway, 提供一个getObjectPtr()来返回T*又不会很麻烦,在需要NULL==object时改成NULL==object.getObjectPtr()也不会死人,即安全又比较方便,何乐而不为,而非要把自己置于language and compiler的死地,何解?

PS,LS说的NULL==object是把NULL和obj都转换的说法是错的,因为原生指针和0比较是无任何多余动作的,这里只有object会被compiler变成object.operator T*(),其实跟getObjectPtr没有什么本质上的不同,只是说隐式转换在语法上看上去比较cool而已。

请自行斟酌~

3

主题

16

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2006-12-11 23:19:00 | 显示全部楼层

Re: Re:求助:如何编写模版类支持NULL==obj的operator

千里马肝: Re:求助:如何编写模版类支持NULL==obj的operator
原生指针和0比较是无任何多余动作的


想问一下这个说法的出处,纯属求教,没有较真或者抬杠的意思。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-26 02:01

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表