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

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

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

#pragma once

#include

/*

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

*/

template

class XMRList

{

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

public:

typedef std::map 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

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

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

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

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

public:

void OnForeach(CStateBase* pState)

{

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

// ......

}

void TestForEach()

{

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

}

};

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

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

#pragma once

#include

/*

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

*/

template

class XMRList

{

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

public:

typedef std::map 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

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

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

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

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

public:

void OnForeach(CStateBase* pState)

{

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

// ......

}

void TestForEach()

{

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

}

};


相关内容

  • 南昌大学C++题库
  • 一.单项选择题 1. 在C++语言中,对函数参数默认值描述正确的是:( ) A) 函数参数的默认值只能设定一个 B) 一个函数的参数若有多个,则参数默认值的设定可以不连续 C) 函数参数必须设定默认值 D) 在设定了参数的默认值后,该参数后面定义的所有参数都必须设定默认值 2. 假定 AB 为一个类 ...

  • 马尔科夫链
  • 一.引言 1.马尔科夫链的数学背景 马尔可夫链,因安德烈•马尔可夫(A.A.Markov,1856-1922)得名,是数学中具有马尔可夫性质的离散时间随机过程.该过程中,在给定当前知识或信息的情况下,过去(即当期以前的历史状态)对于预测将来(即当期以后的未来状态)是无关的. 马尔可夫链是随机变量X_ ...

  • C面试笔试题
  • C/C++ 笔试.面试题目(1) 1.求下面函数的返回值(微软) int func(x) { int countx = 0; while(x) { countx ++; x = x&(x-1); } return countx; } 假定x = 9999. 答案:8 思路:将x转化为2进制, ...

  • C++模拟试卷(一)
  • C++程序设计模拟试卷(一) 一.单项选择题(本大题共20小题,每小题1分,共20分) 在每小题列出的四个备选项中 只有一个是符合题目要求的,请将其代码填写在题后的括号内.错选.多选或未选均无 分. 1. 编写C++程序一般需经过的几个步骤依次是() A. 编辑.调试.编译.连接 B. 编辑.编译. ...

  • 面试常见考题_java基础(全)
  • J2SE 基础 九种基本数据类型的大小,以及他们的封装类. 基本类型:boolean byte char short int long float double void 封装类型:Boolean Byte ● 基本数据类型与其对应的封装类由于本质的不同,具有一些区别: 基本数据类型只能按值传递,而 ...

  • C++拷贝构造函数
  • C++拷贝构造函数 关键字:   C++ 默认拷贝构造函数的行为如下: 默认的拷贝构造函数执行的顺序与其他用户定义的构造函数相同,执行先父类后子类的构造. 拷贝构造函数对类中每一个数据成员执行成员拷贝(memberwise Copy)的动作. a)如果数据成员为某一个类的实例,那么调用此类的拷贝构造 ...

  • 用户在声明类时可以不定义构造函数
  • 用户在声明类时可以不定义构造函数,系统会自动设置一个默认的构造函数,在定义类对象时会自动调用这个默认的构造函数.这个构造函数实际上是一个空函数,不执行任何操作.如果需要对类中的数据成员初始化,应自己定义构造函数. 构造函数的主要作用是对数据成员初始化.在设计派生类的构造函数时,不仅要考虑派生类所增加 ...

  • 华为上机题库整理
  • 以前上机考试编程工具为C/C++:VC 6.0:Java:eclipse,这次改成C/C++: VS2005(或VC6.0) Java:JDK1.7.由于本人以前学C语言花了一些功夫,相对Java用得上手些,备考时用的是C++:临考前一周接到通知,说是要用VS2005,于是下个软件再加上熟悉一下花了 ...

  • 腾讯技术类笔试笔试题(校园)123
  • 一. 单选题(每题4分,15题,共60分) 1.考虑函数原型void hello(int a,int b=7,char* pszC= A hello(5) B.hello(5,8) C.hello(6, 2.下面有关重载函数的说法中正确的是:C A.重载函数必须具有不同的返回值类型 B.重载函数形参 ...