逆水行船

别人的天堂,是我的异乡;无端的繁华,倍添我的惆怅

 

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);

    }

};

 

posted on 2011-07-21 13:49  荣-  阅读(5370)  评论(0编辑  收藏  举报

导航