您的位置:首页 > 移动开发

13) 参数适配ParamterWrapper [原创,泛型编程,自由下载转载,需注明出处]

2013-10-07 13:52 471 查看
我们在写C++接口时,通常会有下列参数形式: 

T, T&以出于不同的需求,比如对于一些内置类型,由于其复制很高效,T及T&没有什么大的区别,我们就可以使用T形式; 但是对于一些比较大的对象,如果用T,则传递过程中会构造临时对象出来,浪费效率;或者对于一些不可复制对象,使用T根本编译不过,就需要使用T&形式;对于一些C程序员或者部分C++程序员来说,可能会使用T*形式,但是这样,就把校验参数的责任交给了接口实现者,有这甚至是不可能的,比如接口返回一个结构体数据,当指针参数为NULL时,返回什么?只能抛出异常。

2.有些时候,系统提供的隐匿转换甚至可以带来错误的逻辑,比如void DemoMP(int);void DemoMP(float&);如果调用 DemoMP(3.56f) 则会匹配 DemoMP(int), 而不是用户期望的 DemoMP(float&), 这完全是调用了错误的接口。

本文章中提供的ParamterWrapper 可以解决这些问题,也可以到我的资源中去下去源代码。

#ifndef objectWrapper_h__

#define objectWrapper_h__

#include "mplconfig.h"

#include "mplmacro.h"

#include <typeinfo>

#include "parameterWrp.h"

/********************************************************************

Description : packaging any type to one unified class, those types have not any relation.

                      e.g. those types have not shard base class , those are not convertible also.

                      It has type traint 

                      It is different with force type cast of C style and it is not different with dynamic_cast/static_cast also.

                      if you cast it to wrong type, it will return NULL.

Author : Shen.Xiaolong (Shen Tony) (2010-2013)

Mail : xlshen2002@hotmail.com,  xlshen@126.com

verified platform : VS2008

copyright:          : latest Version of The Code Project Open License (CPOL : http://www.codeproject.com/)
*********************************************************************/

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace MiniMPL

{

////////////////////////////////////////////////// Base Declaration/////////////////////////////////////////////////////////////

    /*CAnyObject suits to hold different class which have not any relation and any similarity.*/

    class CAnyObject

    {

    public:

        template<typename operatorType> operator operatorType&() const;

        template<typename operatorType> operator operatorType*() const;

        template<typename NewType> NewType cast2Type() const;   //readability interface , same as : T* pNewVal = (T*)(*this);
virtual ~CAnyObject(){};

        virtual void  dump() const = 0 ; 

        virtual const type_info& getRealType() const=0;

    protected:

        CAnyObject(){};

        CAnyObject(CAnyObject const& other);

        CAnyObject& operator=(CAnyObject const& other);

    };

//////////////////////////////////////////////////////// Impl /////////////////////////////////////////////////////////////////

    template<typename objectType> 

    class CAnyObjectImpl : public CAnyObject

    {

    public:

        explicit CAnyObjectImpl(objectType& Obj,bool bAutoDelete)

            :m_pObject(&Obj)

            ,m_bAutoDelete(bAutoDelete)

        {}

        explicit CAnyObjectImpl()

            : m_bAutoDelete(true)

        {

            m_pObject = new objectType();

        }

        template<typename P1>

        explicit CAnyObjectImpl(P1& p1)

            : m_bAutoDelete(true)

        {

            m_pObject = new objectType(p1);

        }

        template<typename P1,typename P2>

        explicit CAnyObjectImpl(P1& p1,P2& p2)

            : m_bAutoDelete(true)

        {

            m_pObject = new objectType(p1,p2);

        }

        template<typename P1,typename P2,typename P3>

        explicit CAnyObjectImpl(P1& p1,P2& p2,P3& p3)

            :m_bAutoDelete(true)

        {

            m_pObject = new objectType(p1,p2,p3);

        }

        virtual ~CAnyObjectImpl()

        {           

            if (m_bAutoDelete && m_pObject)

            {

                Static_Assert(0!=sizeof(objectType));  //check complete type

                delete m_pObject;

                m_pObject   = NULL;

            }

        }

        inline operator objectType&()

        {

            return *getObject();

        }

        inline operator objectType*()

        {

            return getObject();

        }

    protected:

        //CAnyObjectImpl();

        virtual const type_info& getRealType() const

        {

            return typeid(objectType);

        }

        inline objectType* getObject()

        {

            return m_pObject;

        }

        virtual void  dump() const

        { 

            DMUPINFO(("Real Type : %s\n",typeid(objectType).name()));

#if defined(_MSC_VER)

            __if_exists(objectType::dump)

            {

                m_pObject->dump();

            }

#endif

        }

    private:

        objectType*     m_pObject;            

        bool            m_bAutoDelete;          //maintain objectType instance life cycle

    };

    template<typename operatorType>

    CAnyObject::operator operatorType&() const

    {

        operatorType*   pObject = *this; //implement operator operatorType* 

        AssertP(pObject);

        if (NULL == pObject)

        {

            throw 1;

        }

        return *pObject;

    }

    template<typename operatorType>

    CAnyObject::operator operatorType*() const

    {

        /*! Limition : 
the operator Type must be the same with actual type.
operator Type can't be base class because CAnyObject isn't needed for some classes which have shared base class.
In those cases they can use base class pointer directly, instead of  CAnyObject.
CAnyObject suits to hold different class which have not any relation and any similarity.
*/

        if(getRealType()!=typeid(operatorType))

        {

            return NULL;

        }

        return (CAnyObjectImpl<operatorType>&)(*this);   //implement CObjectWrapperImpl::operator objectType*

    }

    template<typename NewType>

    NewType CAnyObject::cast2Type() const

    {

        return *this;

    }

///////////////////////////////////////////////////// maker //////////////////////////////////////////////////////////
template<typename ObjectType>
CAnyObject* bindAnyObject(ObjectType& object,bool bAutoDelete)
{
return new CAnyObjectImpl<ObjectType>(object,bAutoDelete);
}

    template<typename ObjectType>

    CAnyObject* newAnyObject()

    {

        return new CAnyObjectImpl<ObjectType>();            //ObjectType()

    }

    template<typename ObjectType,typename P1>

    CAnyObject* newAnyObject(P1& p1)

    {

        return new CAnyObjectImpl<ObjectType>(p1);          //ObjectType(p1)

    }

    template<typename ObjectType,typename P1>

    CAnyObject* newAnyObject(Paramter<P1>& p1)

    {

        return new CAnyObjectImpl<ObjectType>(p1);          //ObjectType(p1)

    }

    template<typename ObjectType,typename P1,typename P2>

    CAnyObject* newAnyObject(P1& p1,P2& p2)

    {

        return new CAnyObjectImpl<ObjectType>(p1,p2);       //ObjectType(p1,p2)

    }

    template<typename ObjectType,typename P1,typename P2>

    CAnyObject* newAnyObject(Paramter<P1>& p1,Paramter<P2>& p2)

    {

        return new CAnyObjectImpl<ObjectType>(p1,p2);       //ObjectType(p1,p2)

    }

    template<typename ObjectType,typename P1,typename P2,typename P3>

    CAnyObject* newAnyObject(P1& p1,P2& p2,P3& p3)

    {

        return new CAnyObjectImpl<ObjectType>(p1,p2,p3);       //ObjectType(p1,p2,p3)

    }

    template<typename ObjectType,typename P1,typename P2,typename P3>

    CAnyObject* newAnyObject(Paramter<P1>& p1,Paramter<P2>& p2,Paramter<P3>& p3)

    {

        return new CAnyObjectImpl<ObjectType>(p1,p2,p3);       //ObjectType(p1,p2,p3)

    }

}

#endif // objectWrapper_h__

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐