zoukankan      html  css  js  c++  java
  • 插件框架内核完成

    1、所有组件类都支持接口 Ix_Object

    //! 对象基本接口
    /*! 所有组件类都支持该接口
        \interface Ix_Object
        \ingroup _GROUP_PLUGIN_CORE_
        \see 智能指针类: Cx_Ptr, Cx_Interface
    */
    interface Ix_Object
    {
        //! 增加引用计数, 由智能指针类调用
        virtual void AddRef() = 0;

        //! 减少引用计数, 自动释放对象, 由智能指针类调用
        virtual void Release() = 0;
    };

    2、定义一个类来表示组建类ID,这样相对于普通字符串常量而言具有强类型特点,且不是指针

    //! 组件类ID
    class XCLSID
    {
    public:
        //! 默认构造函数
        XCLSID();

        //! 给定UUID串构造
        XCLSID(LPCSTR clsid);

        //! 拷贝构造函数
        XCLSID(const XCLSID& src);

        //! 赋值为一个UUID串的操作符函数
        XCLSID& operator=(LPCSTR clsid);

        //! 赋值操作符函数
        XCLSID& operator=(const XCLSID& src);

        //! 相等操作符函数
        bool operator==(const XCLSID& src) const;

        //! 不相等操作符函数
        bool operator!=(const XCLSID& src) const;

        //! 大于操作符函数
        bool operator>(const XCLSID& src) const;

        //! 小于操作符函数
        bool operator<(const XCLSID& src) const;

        //! 返回内部的ID值
        LPCSTR str() const;

        //! 返回是否为非空的UUID串
        bool valid() const;

    private:
        char m_clsid[40];
    };

    3、提供智能指针类 Cx_Interface 和 Cx_Ptr

    //! 封装特定接口的智能指针类
    /*!
        \ingroup _GROUP_PLUGIN_CORE_
    */
    template <class IF_Type>
    class Cx_Interface
    {
        typedef Cx_Interface<IF_Type> thisClass;
    public:
        //! 缺省构造函数
        Cx_Interface();
        //! 从一个接口指针构造
        template <class IF_Type2>
        explicit Cx_Interface(IF_Type2* pInterface);

        //! 从一个智能指针构造
        template <class IF_Type2>
        explicit Cx_Interface(const Cx_Interface<IF_Type2>& pIF);
        //! 拷贝构造函数
        explicit Cx_Interface(const thisClass& src);

        //! 从一个Cx_Ptr对象构造
        explicit Cx_Interface(const Cx_Ptr& src);
        //! 给定组件类ID创建对象实例
        explicit Cx_Interface(const XCLSID& clsid);
        //! 析构函数
        ~Cx_Interface();
        //! 返回对象接口指针
        IF_Type* P() const;
        //! 调用对象接口函数的操作符
        IF_Type* operator->() const;

        //! 拷贝赋值操作符,复制一个接口指针
        template <class IF_Type2>
        thisClass& operator=(IF_Type2* pInterface);

        //! 拷贝赋值操作符,复制一个智能指针
        template <class IF_Type2>
        thisClass& operator=(const Cx_Interface<IF_Type2>& pIF);

        //! 拷贝赋值操作符,复制同类型的智能指针
        thisClass& operator=(const thisClass& src);
        //! 拷贝赋值操作符,复制Cx_Ptr智能指针
        thisClass& operator=(const Cx_Ptr& src);
        //! 返回两个对象指针是否指向相同的对象
        bool operator==(const IF_Type* pInterface) const;
        //! 返回两个对象指针是否指向不同的对象
        bool operator!=(const IF_Type* pInterface) const;
        //! 返回两个对象指针是否指向相同的对象
        bool operator==(const thisClass& src) const;
        //! 返回两个对象指针是否指向不同的对象
        bool operator!=(const thisClass& src) const;

        //! 相当于 IsNotNull 的转换操作符函数
        operator bool() const;

        //! 相当于 IsNull 的转换操作符函数
        bool operator!() const;
        //! 返回是否没有对象
        bool IsNull() const;
        //! 返回是否有对象
        bool IsNotNull() const;
        //! 立即释放对象指针的引用
        /*! 本对象析构时会自动调用本函数,当对象不再被引用时会自动释放
        */
        void ReleaseInterface();
        //! 分离接口指针
        IF_Type* DetachInterface();
        //! 接管一个接口指针
        void AttachInterface(IF_Type* pIF);
        //! 接管一个接口指针
        void AttachInterface(Ix_Object* pIF);
        //! 给定组件类ID创建有本接口的对象实例
        bool Create(const XCLSID& clsid);
    private:
        void Unload();
        void Load(IF_Type* pIF);
        bool InternalAddRef(IF_Type* pInterface);
        bool InternalRelease(IF_Type* pInterface);
    private:
        IF_Type*    m_pInterface;
    };

    //! 封装Ix_Object接口的智能指针类
    /*!
        \ingroup _GROUP_PLUGIN_CORE_
        \see Cx_Interface
    */
    class Cx_Ptr
    {
    public:
        //! 默认构造函数
        Cx_Ptr();
        //! 从一个接口指针构造
        template <class IF_Type>
        explicit Cx_Ptr(IF_Type* pInterface);

        //! 从一个特定类型的智能指针构造
        template <class IF_Type>
        explicit Cx_Ptr(const Cx_Interface<IF_Type>& pIF);
        //! 拷贝构造函数
        explicit Cx_Ptr(const Cx_Ptr& src);
        //! 给定组件类ID创建对象实例
        explicit Cx_Ptr(const XCLSID& clsid);
        //! 析构函数
        ~Cx_Ptr();
        //! 返回对象接口指针
        Ix_Object* P() const;
        //! 拷贝赋值操作符,复制一个接口指针
        template <class IF_Type>
        Cx_Ptr& operator=(IF_Type* pInterface);

        //! 拷贝赋值操作符,复制一个特定类型的智能指针
        template <class IF_Type>
        Cx_Ptr& operator=(const Cx_Interface<IF_Type>& pIF);
        //! 拷贝赋值操作符,复制同类型的智能指针
        Cx_Ptr& operator=(const Cx_Ptr& src);
        //! 返回两个对象指针是否指向相同的对象
        bool operator==(const Ix_Object* pInterface) const;
        //! 返回两个对象指针是否指向不同的对象
        bool operator!=(const Ix_Object* pInterface) const;
        //! 返回两个对象指针是否指向相同的对象
        bool operator==(const Cx_Ptr& src) const;
        //! 返回两个对象指针是否指向不同的对象
        bool operator!=(const Cx_Ptr& src) const;

        //! 相当于 IsNotNull 的转换操作符函数
        operator bool() const;

        //! 相当于 IsNull 的转换操作符函数
        bool operator!() const;
        //! 返回是否没有对象
        bool IsNull() const;
        //! 返回是否有对象
        bool IsNotNull() const;
        //! 立即释放对象指针的引用
        /*! 本对象析构时会自动调用本函数,当对象不再被引用时会自动释放
        */
        void ReleaseInterface();
        //! 分离接口指针
        Ix_Object* DetachInterface();
        //! 接管一个接口指针
        void AttachInterface(Ix_Object* pIF);
        //! 给定组件类ID创建对象实例
        bool Create(const XCLSID& clsid);
    private:
        void Unload();
        void Load(Ix_Object* pIF);
    private:
        Ix_Object*    m_pInterface;
    };

    4、使用下列宏注册组件类

    // XBEGIN_DEFINE_MODULE()
    //     XDEFINE_CLASSMAP_ENTRY(clsid, cls)
    //     XDEFINE_CLASSMAP_ENTRY_Singleton(clsid, cls)
    //     XDEFINE_SPECIAL_INTERFACE_ENTRY_Singleton(clsid, iid, cls)
    // XEND_DEFINE_MODULE()
    //
    // XMODULE_INIT(hInstance)
    // XMODULE_FREE()

    5、测试代码(均通过):

    interface IA
    {
        virtual void f1() = 0;
    };

    interface IB
    {
        virtual void f2() = 0;
    };

    struct CSimple : IA, IB, Ix_Object
    {
        void f1() {}
        void f2() {}
        void AddRef() {}
        void Release() {}
    };

    const XCLSID CLSID_A("986f229c-6a08-4275-9677-895a2460590c");

    void TestPtr()
    {
        CSimple obj;
        Ix_Object* pObj = &obj;
        IA* pA = &obj;
        IB* pB = &obj;

        Cx_Ptr obj1(pA);                // Cx_Ptr(其他接口的指针)
        Cx_Ptr obj2(pObj);                // Cx_Ptr(Ix_Object*)
        Cx_Ptr obj3(obj1);                // Cx_Ptr(Cx_Ptr)
        obj1 = pB;                        // Cx_Ptr = 其他接口的指针
        obj1 = pObj;                    // Cx_Ptr = Ix_Object*
        obj1 = obj2;                    // Cx_Ptr = Cx_Ptr
        obj3 == pObj;                    // Cx_Ptr == Ix_Object*

        Cx_Interface<IA> pIFA1(pObj);    // Cx_Interface(Ix_Object*)
        Cx_Interface<IA> pIFA2(pA);        // Cx_Interface(同类型接口的指针)
        Cx_Interface<IA> pIFA3(pB);        // Cx_Interface(其他类型接口的指针)
        Cx_Interface<IB> pIFB1(obj1);    // Cx_Interface(Cx_Ptr)
        Cx_Interface<IB> pIFB2(pIFB1);    // Cx_Interface(Cx_Interface) 同类型
        Cx_Interface<IB> pIFB3(pIFA1);    // Cx_Interface(Cx_Interface) 其他类型
        pIFA1 = pObj;                    // Cx_Interface = Ix_Object*
        pIFA1 = pA;                        // Cx_Interface = 同类型接口的指针
        pIFA1 = pB;                        // Cx_Interface = 其他类型接口的指针
        pIFA1 = obj1;                    // Cx_Interface = Cx_Ptr
        pIFA1 = pIFA2;                    // Cx_Interface = Cx_Interface 同类型
        pIFA1 = pIFB2;                    // Cx_Interface = Cx_Interface 其他类型
        pIFA1 == pA;                    // Cx_Interface == 同类型接口的指针

        Cx_Ptr obj4(pIFA1);                // Cx_Ptr(Cx_Interface)
        obj1 = pIFA1;                    // Cx_Ptr = Cx_Interface

        Cx_Ptr obj5(CLSID_A);            // Cx_Ptr(clsid)
        obj5.Create(CLSID_A);            // Cx_Ptr.Create

        Cx_Interface<IB> pIFB5(CLSID_A);    // Cx_Interface(clsid)
        pIFB5.Create(CLSID_A);            // Cx_Interface.Create
    }

  • 相关阅读:
    操作系统-多进程图像
    025.Kubernetes掌握Service-SVC基础使用
    Linux常用查看版本指令
    使用动态SQL处理table_name作为输入参数的存储过程(MySQL)
    INTERVAL 用法 mysql
    sql server编写archive通用模板脚本实现自动分批删除数据【填空式编程】
    docker部署redis集群
    Ubuntu1804下安装Gitab
    Bash脚本编程学习笔记06:条件结构体
    KVM虚拟化基础
  • 原文地址:https://www.cnblogs.com/rhcad/p/1616380.html
Copyright © 2011-2022 走看看