• C++中,以类成员函数指针作为参数对std::map中的元素进行迭代处理 荣


    C++中使用Map会遇到迭代Map中元素的问题,使用for循环迭代元素,无形中增加了一层括号;使用函数指针调用类成员函数时,通常做法是,提供一个静态函数作为函数指针指向的函数,在静态函数中提供类指针对成员函数的调用。下面的代码通过foreach模板函数提供解决这两种问题的一个实例。

     

    #pragma once

    #include <map>

     

    /*

    托管Map的类,Map中存储着对象的指针

    */

    template<typename S>

    class XMRList

    {

        // 重定义Map的类型别名,迭代器的类型别名,易于阅读

    public:

        typedef std::map<long, S*> MyMAP;

        typedef typename MyMAP::iterator MyIterator;

        typedef typename MyMAP::const_iterator MyConstIterator;

     

        // 构造函数

    public:

        XMRList()  {   }

     

        ~XMRList() {this->ReslaseList();}

    public:

     

        // Map中查询对象,查询失败时,返回空指针

        S* Find(long id)

        {

           MyIterator it = this->m_Map.find(id);

           if (it != this->m_Map.end())

           {

               return it->second;

           }

     

           return NULL;

        }

     

        // Map中查询对象,查询失败时,返回空指针

        S* Find(long id) const

        {

           MyConstIterator it = this->m_Map.find(id);

           if (it != this->m_Map.end())

           {

               return it->second;

           }

     

           return NULL;

        }

     

        // 取得Map的大小

        UINT GetCount() const

        {

           return this->m_Map.size();

        }

     

        MyIterator Begin()

        {

           return this->m_Map.begin();

        }

     

        MyConstIterator Begin() const

        {

           return this->m_Map.begin();

        }

        MyIterator End()

        {

           return this->m_Map.end();

        }

     

        MyConstIterator End() const

        {

           return this->m_Map.end();

        }

     

    public:

     

        // 遍历Map中的对象,并调用相关类成员函数(1个参数)进行处理

        template<typename T, typename R>

           void   foreach(T& o, R (T::* f)(S*))

        {

           MyIterator begin = this->m_Map.begin();

           MyIterator end = this->m_Map.end();

           for (; begin != end; ++begin)

           {

               (o.*f)(begin->second);

           }

        }

     

        // 遍历Map中的对象,并调用相关类成员函数(2个参数)进行处理

        template<typename T, typename R, typename A>

           void foreach(T& o, A arg, R (T::* f)(S*, A))

        {

           MyIterator begin = this->m_Map.begin();

           MyIterator end = this->m_Map.end();

           for (; begin != end; ++begin)

           {

               (o.*f)(begin->second, arg);

           }

        }

     

        // 遍历Map中的对象,并调用相关类成员函数(3个参数)进行处理

        template<typename T, typename R, typename A2, typename A3>

           void foreach(T& o, A2 arg2, A3 arg3, R (T::* f)(S*, A2, A3))

        {

           MyIterator begin = this->m_Map.begin();

           MyIterator end = this->m_Map.end();

           for (; begin != end; ++begin)

           {

               (o.*f)(begin->second, arg2, arg3);

           }

        }

     

        // 遍历Map中的对象,并调用相关类成员函数(4个参数)进行处理

        template<typename T, typename R, typename A2, typename A3, typename A4>

           void foreach(T& o, A2 arg2, A3 arg3, A4 arg4, R (T::* f)(S*, A2, A3, A4))

        {

           MyIterator begin = this->m_Map.begin();

           MyIterator end = this->m_Map.end();

           for (; begin != end; ++begin)

           {

               (o.*f)(begin->second, arg2, arg3, arg4);

           }

        }

     

    public:

        // 为减少对map的依赖,提供的遍历map的函数

        // foreach处理不了模板函数的问题,所以提供该函数

        bool GetNextItor(MyIterator& itor)

        {

           if (itor == this->m_Map.end())

           {

               itor = this->m_Map.begin();

               return true;

           }

     

           ++itor;

     

           if (itor == this->m_Map.end())

           {

               return false;

           }

     

           return true;

        }

     

        // 为减少对map的依赖,提供的遍历map的函数

        // foreach处理不了模板函数的问题,所以提供该函数

        bool GetNextItor(MyConstIterator& itor) const

        {

           if (itor == this->m_Map.end())

           {

               itor = this->m_Map.begin();

               return true;

           }

     

           ++itor;

     

           if (itor == this->m_Map.end())

           {

               return false;

           }

     

           return true;

        }

     

    private:

        void ReslaseList()       // 释放集合中的数据

        {

           for (MyIterator it = this->m_Map.begin(); it != this->m_Map.end(); ++it)

           {

               delete it->second;

               it->second = NULL;

           }

     

           this->m_Map.clear();

        }

     

    public:

        MyMAP m_Map;  // 托管的集合

    };

     

    函数的调用:

     

    class CStateBase

    {

    public:

        long m_ID;

    }

    class MapTest

    {

    public:

        XMRList<CStateBase>  m_MapProxy;

    public:

        void OnForeach(CStateBase* pState)

        {

           TRACE("遍历Map元素,编号:%d\n", pState->m_ID);

           // ......

        }

     

        void TestForEach()

        {

           this->m_MapProxy.foreach(*this, &MapTest::OnForeach);

        }

    };

     

  • 相关阅读:
    Asp.Net根据角色验证
    牛客登录(四)
    外键约束
    update 和replace更新表
    每日一题力扣485
    牛客登录(6)开窗函数
    牛客登录(5)
    MySQL的UPDATE或DELETE中子查询不能为同一张表
    牛客登录(二)
    剑指offer:二分
  • 原文地址:https://www.cnblogs.com/admin11/p/2112720.html
Copyright © 2020-2023  润新知