复习C++基础知识-----“我的第一本C++”读书笔记4(终篇)
vector : 需要保存大量数据的时候
map : 用来实现查找表,或者用来存储稀疏数组或稀疏矩阵
list : 频繁地对序列的中部进行插入和删除操作
deque : 当大部分插入和删除发生在序列的头部或尾部时
array : 固定长度的数组
STL算法
1)用for_each()算法遍历容器中的数据元素
for_each()的参数分别是开始位置、结束位置、处理函数
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current value add 10 : " << iValue + 10 << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecSalary;
vecSalary.push_back( 10 );
vecSalary.push_back( 20 );
vecSalary.push_back( 30 );
vecSalary.push_back( 40 );
vecSalary.push_back( 50 );
cout << "display the value:" << endl;
for_each( vecSalary.begin(), vecSalary.end(), vecDisplay );
return 0;
}
2)用find算法实现线性查找-----判断容器中是否存在特定的数据
find()的参数分别是开始位置、结束位置、要查找的数据
#include "stdafx.h"
#include "vector"
#include "algorithm"
#include "string"
#include "iostream"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> vecStudentName;
vecStudentName.push_back( "zengraoli" );
vecStudentName.push_back( "125308501" );
vecStudentName.push_back( "test" );
vecStudentName.push_back( "find" );
const string strFindName = "125308501";
vector<string>::iterator it = find( vecStudentName.begin(), vecStudentName.end(), strFindName );
if (vecStudentName.end() != it)
{
cout << "vecStudentName is exist this string 125308501 !" << endl;
}
it = find( vecStudentName.begin(), vecStudentName.end(), "125308502" );
if ( vecStudentName.end() == it )
{
cout << "vecStudentName isn't exist this string 125308502 !" << endl;
}
return 0;
}
3)用find_if()算法实现线性查找-----判断容器中是否存在指定范围的数据
find_if()的参数分别是开始位置、结束位置、所定义的要查找的条件(以bool(int)函数来表示)
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "algorithm"
#include "vector"
#define FIND_VALUE_TERMS 6
bool isPass( int n )
{
return n >= FIND_VALUE_TERMS;
}
void vecDisplay( int iValue )
{
cout << "current container value is : " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecScores;
for ( int i = 1; i <= 10; i++ )
{
vecScores.push_back( i );
}
vector< int >::iterator it = vecScores.begin();
do
{
it = find_if( it, vecScores.end(), isPass );
if (it != vecScores.end())
{
cout << "meet the conditions : " << ( *it ) << endl;
it++; // this iterator point next
}
else
{
break;
}
} while (true);
return 0;
}
4)用remove()实现移除、replace()实现替换
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "algorithm"
#include "vector"
#define FIND_VALUE_TERMS 6
void vecDisplay( int iValue )
{
cout << "current container value is : " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecScores;
for ( int i = 1; i <= 10; i++ )
{
vecScores.push_back( i );
// vecScores.push_back( 9 );
}
cout << "used function remove" << endl;
const int removeValue = 8;
remove( vecScores.begin(), vecScores.end(), removeValue );
for_each( vecScores.begin(), vecScores.end(), vecDisplay );
cout << "\n";
cout << "used function replace" << endl;
const int replaceValue = 9;
const int newValue = 999;
replace( vecScores.begin(), vecScores.end(),replaceValue, newValue );
for_each( vecScores.begin(), vecScores.end(), vecDisplay );
return 0;
}
5)复制容器元素 : copy()
有时需要将一个容器中的元素复制到另一个容器中区,来完成数据的备份或者进行其他处理。
vector<float>::iterator lastPos在使用的时候,指向的是某个具体的数据而不是该数据的pos。
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecScore;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 80.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
vecScore.resize( vecScoreFirst.size() + vecScoreSecond.size() ); // resize vecScore
vector< float >::iterator lastPos = copy( vecScoreFirst.begin(), vecScoreFirst.end(), vecScore.begin() );
copy( vecScoreSecond.begin(), vecScoreSecond.end(), lastPos );
cout << "\n" << endl;
cout << "vecScore current value:" << endl;
for_each( vecScore.begin(), vecScore.end(), vecDisplay );
return 0;
}
6)复制容器元素 : copy_backward()
从后向前覆盖
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecScore;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 80.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
cout << "\n" << endl;
vecScore.resize( vecScoreFirst.size() + vecScoreSecond.size() ); // resize vecScore
cout << "vecScore size is : " << vecScore.size() << endl;
copy( vecScoreFirst.begin(), vecScoreFirst.end(), vecScore.begin() );
copy_backward( vecScoreSecond.begin(), vecScoreSecond.end(), vecScore.end() );
cout << "\n" << endl;
cout << "vecScore current value:" << endl;
for_each( vecScore.begin(), vecScore.end(), vecDisplay );
return 0;
}
7)合并容器元素 : merge()
类似copy的用法
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecResutl;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 60.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
// used merge the two container must to pass through sort, otherwise error
vecResutl.resize( vecScoreFirst.size() + vecScoreSecond.size() );
merge( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecScoreSecond.end(), vecResutl.begin() );
cout << "\n" << endl;
cout << "vecScore current value:" << endl;
for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
return 0;
}
8)set_union()
合并之后去掉两个容器中重复的部分
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecResutl;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 60.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
// used merge the two container must to pass through sort, otherwise error
vecResutl.resize( vecScoreFirst.size() + vecScoreSecond.size() );
set_union( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecScoreSecond.end(), vecResutl.begin() );
cout << "\n" << endl;
cout << "vecScore current value:" << endl;
for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
return 0;
}
9)transform()
在进行元素的复制时,同时对元素进行某些操作
transform有两种使用方式,分别对应的func参数不同
#include "stdafx.h"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
#define ADD_VALUE 10
// used transform the first form
int firstAddFunc( int iValue )
{
return iValue + ADD_VALUE;
}
// used transform the first form
int secondAddFunc( int iLeftValue, int iRightValue )
{
return iLeftValue + iRightValue;
}
void vecDisplay( int iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<float> vecScoreFirst;
vector<float> vecScoreSecond;
vector<float> vecResutl;
for ( int i = 0; i < 10; i++ )
{
vecScoreFirst.push_back( 60.0f + i );
}
cout << "vecScoreFirst current value:" << endl;
for_each( vecScoreFirst.begin(), vecScoreFirst.end(), vecDisplay );
for ( int i = 0; i < 10; i++ )
{
vecScoreSecond.push_back( 80.0f + i );
}
cout << "\n" << endl;
cout << "vecScoreSecond current value:" << endl;
for_each( vecScoreSecond.begin(), vecScoreSecond.end(), vecDisplay );
// used transform the first form
vecResutl.resize( vecScoreFirst.size() );
transform( vecScoreFirst.begin(), vecScoreFirst.end(), vecResutl.begin(), firstAddFunc );
cout << "\n" << endl;
cout << "transform the first form vecScore current value:" << endl;
for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
// used transform the second form
vecResutl.clear();
vecResutl.resize( vecScoreFirst.size() );
transform( vecScoreFirst.begin(), vecScoreFirst.end(), vecScoreSecond.begin(), vecResutl.begin(), secondAddFunc );
cout << "\n" << endl;
cout << "transform the second form vecScore current value:" << endl;
for_each( vecResutl.begin(), vecResutl.end(), vecDisplay );
return 0;
}
10)sort()、reverse()
排序和翻转算法
#include "stdafx.h"
#include "string"
#include "iostream"
using namespace std;
#include "vector"
#include "algorithm"
void vecDisplay( const string iValue )
{
cout << "current container value is: " << iValue << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<string> vecStudentName;
vector<string>::iterator it;
vecStudentName.push_back( "zeng" );
vecStudentName.push_back( "zengraoli" );
vecStudentName.push_back( "zengRaoli" );
vecStudentName.push_back( "test" );
vecStudentName.push_back( "125308501" );
vecStudentName.push_back( "zengRaoli2" );
vecStudentName.push_back( "1zeng" );
cout << "vecStudentName current value:" << endl;
for( it = vecStudentName.begin(); it != vecStudentName.end(); it++ )
{
cout << "vecScore current value:" << ( *it ) << endl;
}
// used sort algorithm
sort( vecStudentName.begin(), vecStudentName.end() );
cout << "\n" << endl;
cout << "pass sort vecStudentName current value:" << endl;
for_each( vecStudentName.begin(), vecStudentName.end(), vecDisplay );
// used reverse algorithm
reverse( vecStudentName.begin(), vecStudentName.end() );
cout << "\n" << endl;
cout << "pass reverse vecStudentName current value:" << endl;
for_each( vecStudentName.begin(), vecStudentName.end(), vecDisplay );
return 0;
}
更改对基本数据类型的sort算法:
#include "stdafx.h"
#include "string"
#include "vector"
#include "algorithm"
#include "assert.h"
#include "iostream"
using namespace std;
void vecDisplay( const int iValue )
{
cout << "current value is " << iValue << endl;
}
// my sort algorithm
bool defineSort( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecIValue;
vecIValue.push_back( 9 );
vecIValue.push_back( 1 );
vecIValue.push_back( 3 );
vecIValue.push_back( 5 );
vecIValue.push_back( 8 );
vecIValue.push_back( 7 );
vecIValue.push_back( 2 );
/*
sort( vecIValue.begin(), vecIValue.end() );
cout << "pass sort : " << endl;
for_each( vecIValue.begin(), vecIValue.end(), vecDisplay );
*/
sort( vecIValue.begin(), vecIValue.end(), defineSort );
cout << "pass sort : " << endl;
for_each( vecIValue.begin(), vecIValue.end(), vecDisplay );
return 0;
}
针对于自定义类型的sort算法
需要重写 < 号,暂时类里面不带有指针变量,否则还要重写拷贝构造
#include "stdafx.h"
#include "string"
#include "vector"
#include "algorithm"
#include "assert.h"
#include "iostream"
using namespace std;
namespace Zeng
{
class CTest_Rectang
{
public:
CTest_Rectang( int iLong, int iWidth, int iHeight )
: m_iLong( iLong ), m_iWidth( iWidth ), m_iHeight( iHeight )
{
}
bool operator < ( const CTest_Rectang& rCTest_Rectang )
{
assert( rCTest_Rectang.m_iLong );
if ( rCTest_Rectang.m_iLong > this->m_iLong )
{
return true;
}
return false;
}
friend void vecDisplay( const CTest_Rectang& rCTest_Rectang );
private:
int m_iLong;
int m_iWidth;
int m_iHeight;
};
void vecDisplay( const Zeng::CTest_Rectang& rCTest_Rectang )
{
cout << "current container Zeng::CTest_Rectang m_iLong is: " << rCTest_Rectang.m_iLong << endl;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<Zeng::CTest_Rectang> vecCTestRectang;
for ( int i = 0; i < 8; i++ )
{
vecCTestRectang.push_back( Zeng::CTest_Rectang( 14 + i, 14, 14 ) );
}
// used sort algorithm
sort( vecCTestRectang.begin(), vecCTestRectang.end() );
cout << "\n" << endl;
cout << "pass sort vecStudentName current value:" << endl;
for_each( vecCTestRectang.begin(), vecCTestRectang.end(), Zeng::vecDisplay );
// used reverse algorithm
reverse( vecCTestRectang.begin(), vecCTestRectang.end() );
cout << "\n" << endl;
cout << "pass reverse vecStudentName current value:" << endl;
for_each( vecCTestRectang.begin(), vecCTestRectang.end(), Zeng::vecDisplay );
return 0;
}
11)min_element()、max_element()
取最大最小值算法,容器需要经过sort排序
找到后输出后面的全部值
#include "stdafx.h"
#include "string"
#include "vector"
#include "algorithm"
#include "assert.h"
#include "iostream"
using namespace std;
void vecDisplay( const int iValue )
{
cout << "current value is " << iValue << endl;
}
// my sort algorithm
bool defineSort( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<int> vecIValue;
vecIValue.push_back( 7 );
vecIValue.push_back( 8 );
vecIValue.push_back( 3 );
vecIValue.push_back( 1 );
vecIValue.push_back( 9 );
vecIValue.push_back( 5 );
vecIValue.push_back( 2 );
vector<int>::iterator it;
it = max_element( vecIValue.begin(), vecIValue.end() );
for ( ; it != vecIValue.end(); it++ )
{
cout << "max_element current value is : " << ( *it ) << endl;
}
cout << "\n" << endl;
it = min_element( vecIValue.begin(), vecIValue.end() );
for ( ; it != vecIValue.end(); it++ )
{
cout << "min_element current value is : " << ( *it ) << endl;
}
return 0;
}
函数指针
1)
根据函数指针所指向函数的不同,需要根据函数的具体声明来定义一个函数指针,其语法格式如下:
函数返回值类型标识符 ( 指针变量名 )( 形参列表 );
由于"()"的优先级高于"*",所以指针变量名外的括号必不可少。形参列表表示指针变量指向的函数所带的参数列表。
2)
例如有一个函数
void PrintPass( int iLeft, int iRightValue );
如果要声明一个函数指针
void ( *pFunc )( int iLeft, int iRightValue );
省略形参后
void ( *pFunc )( int, int );
如果要定义多个同一类型的指针,还可以使用typedef关键字定义一种新的函数之着呢的数据类型,用这种新的数据类型来定义函数指针,例如
// 定义一种新的函数指针的数据类型
typedef bool ( *pFunc )( int, int );
// 使用新的数据类型定义函数指针
pFunc pMax;
// 直接指向函数
pMax = Max;
#include "stdafx.h"
#include "iostream"
using namespace std;
typedef bool ( *pFunc )( int, int );
bool Max( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
pFunc pMax;
pMax = Max;
cout << "pMax( 5, 6 ) this return bool value is : " << pMax( 5, 6 ) << endl;
cout << "pMax( 6, 5 ) this return bool value is : " << pMax( 6, 5 ) << endl;
return 0;
}
3)
可以在声明的时候不使用typedef直接用auto作为函数指针的数据类型来声明一个函数指针,
auto pMax = Max; // 只能在vs2010上面才使用有效
#include "stdafx.h"
#include "iostream"
using namespace std;
int Max( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
auto pMaxSendcont = Max;
cout << "pMaxSendcont( 5, 6 ) this return bool value is : " << pMaxSendcont( 5, 6 ) << endl;
cout << "pMaxSendcont( 6, 5 ) this return bool value is : " << pMaxSendcont( 6, 5 ) << endl;
return 0;
}
用函数指针实现回调函数
1)
回调函数就是一个通过函数指针调用的函数。如果吧函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,就说这事回调函数。回调函数不是由该函数的实现方直接
调用,而是特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
2)
回调函数实现的机制是:
a、定义一个回调函数
b、提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者
c、当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理
3)为什么要使用回调函数
因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数
#include "stdafx.h"
#include "iostream"
using namespace std;
typedef bool ( *PMAXFUNC )( int, int );
void PrintMessage( int iLeftValue, int iRightValue, PMAXFUNC pMax )
{
cout << "Print Header :" << endl;
cout << "====================================================" << endl;
cout << "pMax LeftValue is : " << iLeftValue << endl;
cout << "pMax RightValue is : " << iRightValue << endl;
cout << "pMax function return is : " << pMax( iLeftValue, iRightValue ) << endl;
cout << "====================================================" << endl;
cout << "Print ender :" << endl;
}
bool Max( const int iLeftValue, const int iRightValue )
{
return ( iLeftValue > iRightValue );
}
int _tmain(int argc, _TCHAR* argv[])
{
PMAXFUNC pMax = Max;
PrintMessage( 5, 6, pMax );
return 0;
}
4)将函数指针应用到STL算法中
ptr_fun()函数将一个普通函数指针转换为一个函数对象
bind1st()函数将整个函数对象的第一个参数绑定为nStandardHeigth
a、在count_if()算法中实现规则和统计标准的完全自定义:
#include "stdafx.h"
#include "vector"
#include "string"
#include "algorithm"
#include "functional"
#include "iostream"
using namespace std;
#define STANDARHEIGHT 165
#define STUDENTNUM 5
class CStudent
{
public:
CStudent( int iHeight ) : m_iHeight( iHeight )
{
}
int GetHeight() const
{
return m_iHeight;
}
private:
int m_iHeight;
};
bool countHeight( int iHeight, const CStudent st)
{
return st.GetHeight() > iHeight;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<CStudent> vecStudent;
for (int i = 0; i < STUDENTNUM; i++)
{
vecStudent.push_back( CStudent( STANDARHEIGHT - 10 + i * 10 ) );
}
const int nStandarHeight = STANDARHEIGHT;
int iCount = count_if( vecStudent.begin(), vecStudent.end(), bind1st( ptr_fun( countHeight ), nStandarHeight ) );
cout << "the student height greater than Standar Number is : " << iCount << endl;
return 0;
}
bind1st()函数将整个函数对象的第一个参数绑定为nStandardHeigth,而函数对象的第二个参数就是iron国企中的CStudent对象作为参数调用countHeight()这个重新定义的统计规则函数,以实现
统计规则和统计标准的完全自定义。
b、在算法中使用指向某个类的成员函数的函数指针
#include "stdafx.h"
#include "vector"
#include "string"
#include "algorithm"
#include "functional"
#include "iostream"
using namespace std;
class CStudent
{
public:
CStudent( string strName )
{
m_strName = strName;
}
bool isNamed( string strName )
{
return strName == m_strName;
}
private:
string m_strName;
};
int _tmain(int argc, _TCHAR* argv[])
{
vector<CStudent> vecStudent;
vecStudent.push_back( CStudent( "zengraoli1" ) );
vecStudent.push_back( CStudent( "zengraoli2" ) );
vecStudent.push_back( CStudent( "zengraoli3" ) );
string strFindName = "zengraoli2";
vector<CStudent>::iterator it = find_if( vecStudent.begin(), vecStudent.end(),
bind2nd( mem_fun_ref( &CStudent::isNamed ), strFindName ) );
if ( it != vecStudent.end() )
{
cout << "找到了对应的vecStudent!" << endl;
}
return 0;
}
在这段代码中,&CStudent::isNamed去的成员函数isNamed()的地址,也就是获得了指向这个成员函数的函数指针;然后使用mem_fun_ref()函数将这个函数指针构造成一个函数对象,如果容器中保存的是指向对象的指针,就应该使用mem_fun_ref()函数来完成这一任务。
因为这个成员函数需要一个蚕食,所以更进一步的,使用bind2nd()函数绑定其第二个参数strFindName来作为查找条件。因为这是一个类的成员函数指针,所以容器中的对象会作为默认隐含的第一个参数。
=====================================================================
函数指针配合STL算法的应用,将STL算法的通用性发挥到了极致。
函数对象
1)所谓函数对象,就是定义了函数调用操作符(function-call operator),即operator()的普通类的对象。在重载的函数调用操作符中,可以实现函数的所有功能。同事,因为类具有属性,可以将每次
函数调用的状态数据保存到他的属性中,这样函数对象就不会像函数指针那样失忆了,从而可以应用在更广的范围内。
2)定义一个模板函数对象
------------------------------------------------------
template <typename T>
class myMax
{
T operator()(T a, T b)
{
return ( a > b ? a : b );
}
};
3)在STL中使用函数对象
------------------------------------------------------
#include "stdafx.h"
#include "vector"
#include "algorithm"
#include "iostream"
using namespace std;
namespace Zeng
{
class CStudent
{
public:
CStudent( int nHeight ) : m_nHieght( nHeight )
{
}
int GetHeight()
{
return m_nHieght;
}
private:
int m_nHieght;
};
class CAverageHeight
{
public:
CAverageHeight() : m_nCount( 0 ), m_nTotalHeight( 0 )
{
}
void operator ()( CStudent st )
{
m_nTotalHeight += st.GetHeight();
m_nCount++;
}
int GetCount()
{
return m_nCount;
}
int GetTotalHeight()
{
return m_nTotalHeight;
}
float GetAverageHeight()
{
if ( 0 != m_nCount )
{
return static_cast<float>( GetTotalHeight() / GetCount() );
}
return 0;
}
private:
int m_nCount;
int m_nTotalHeight;
};
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<Zeng::CStudent> vecStudent;
vecStudent.push_back( Zeng::CStudent( 155 ) );
vecStudent.push_back( Zeng::CStudent( 165 ) );
vecStudent.push_back( Zeng::CStudent( 175 ) );
vecStudent.push_back( Zeng::CStudent( 185 ) );
vecStudent.push_back( Zeng::CStudent( 195 ) );
// use function object
Zeng::CAverageHeight ah;
// use function object in the stl algorithm
ah = for_each( vecStudent.begin(), vecStudent.end(), ah);
cout << "average height is : " << ah.GetAverageHeight() << endl;
cout << "the student count is : " << ah.GetCount() << endl;
return 0;
}
说明:在这里创建了一个函数对象ah并将它应用到for_each()算法中,for_each()算法会以容器中的每个Student对象为参数来对这个函数对象的"()"操作符进行调用。这时,函数对象自然就会将每个
Student对象的身高累加到它自己的m_nTotalHeight属性上,同事它还会记录已经统计过的对象数目。最后,for_each()算法会将完成统计后的函数对象作为结果返回,而这时的函数对象ah已经是一个保存了统计结果的函数对象了。通过函数对象提供的接口函数,可以轻松地获得统计结果并进行输出。
还可以这么用:
#include "stdafx.h"
#include "vector"
#include "algorithm"
#include "iostream"
using namespace std;
namespace Zeng
{
class CStudent
{
public:
CStudent( int nHeight ) : m_nHieght( nHeight )
{
}
int GetHeight()
{
return m_nHieght;
}
private:
int m_nHieght;
};
class CAverageHeight
{
public:
CAverageHeight() : m_nCount( 0 ), m_nTotalHeight( 0 )
{
}
void operator ()( CStudent st )
{
m_nTotalHeight += st.GetHeight();
m_nCount++;
}
operator float()
{
return GetAverageHeight();
}
operator int()
{
return GetCount();
}
int GetCount()
{
return m_nCount;
}
int GetTotalHeight()
{
return m_nTotalHeight;
}
float GetAverageHeight()
{
if ( 0 != m_nCount )
{
return static_cast<float>( GetTotalHeight() / GetCount() );
}
return 0;
}
private:
int m_nCount;
int m_nTotalHeight;
};
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<Zeng::CStudent> vecStudent;
vecStudent.push_back( Zeng::CStudent( 155 ) );
vecStudent.push_back( Zeng::CStudent( 165 ) );
vecStudent.push_back( Zeng::CStudent( 175 ) );
vecStudent.push_back( Zeng::CStudent( 185 ) );
vecStudent.push_back( Zeng::CStudent( 195 ) );
// use function object
float fAverHeight = for_each( vecStudent.begin(), vecStudent.end(), Zeng::CAverageHeight() );
cout << "average height is : " << fAverHeight << endl;
int iCount = for_each( vecStudent.begin(), vecStudent.end(), Zeng::CAverageHeight() );
cout << "average height is : " << iCount << endl;
return 0;
}