C++中的仿函數
零、小序
仿函數是C++中一個強大的解決問題的手段,對於初學者來說這個詞可能比較陌生,但是如果你學習過C++的STL,你可能對這個詞就不陌生了,也或許你已經在使用C++中預定義的默認仿函數只是你不知道它而已。下面這篇文章就爲你揭開仿函數的神祕面紗,也希望通過這篇文章的學習,能夠幫助你提高工作的效率。
一、仿函數介紹
1、仿函數概念
仿函數是定義了一個含有operator()成員函數的對象,可以視爲一個一般的函數,只不過這個函數功能是在一個類中的運算符operator()中實現,是一個函數對象,它將函數作爲參數傳遞的方式來使用。
2、仿函數的優缺點
優點:
1)仿函數比函數指針的執行速度快,函數指針時通過地址調用,而仿函數是對運算符operator進行自定義來提高調用的效率。
2)仿函數比一般函數靈活,可以同時擁有兩個不同的狀態實體,一般函數不具備此種功能。
3)仿函數可以作爲模板參數使用,因爲每個仿函數都擁有自己的類型。
缺點:
1)需要單獨實現一個類。
2)定義形式比較複雜。
3、仿函數作用
仿函數通常有下面四個作用:
1)作爲排序規則,在一些特殊情況下排序是不能直接使用運算符<或者>時,可以使用仿函數。
2)作爲判別式使用,即返回值爲bool類型。
3)同時擁有多種內部狀態,比如返回一個值得同時並累加。
4)作爲算法for_each的返回值使用。
二、仿函數使用代碼示例
1、仿函數作爲排序規則示例
// functionObject.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include <iostream>
#include <string>
#include <set>
using namespace std;
// 學生的名字和分數
class Student
{
public:
string getName()
{
return m_name;
};
int getScore()
{
return m_score;
}
public:
string m_name;
int m_score;;
};
// 根據學生的名字進行排序
class StudentSortRule
{
public:
bool operator()(Student S1, Student S2)
{
return (S1.getName() < S2.getName());
};
};
int main()
{
cout << "----------------仿函數作爲排序規則使用--------------" << endl;
typedef set<Student, StudentSortRule> StudentSet;
StudentSet stuSet;
stuSet.clear();
Student stuJack;
stuJack.m_name = "Jack";
stuJack.m_score = 80;
Student stuToby;
stuToby.m_name = "Toby";
stuToby.m_score = 90;
Student stuISmileLi;
stuISmileLi.m_name = "ISmileLi";
stuISmileLi.m_score = 100;
// 插入數值
stuSet.insert(stuJack);
stuSet.insert(stuToby);
stuSet.insert(stuISmileLi);
// 打印查看
StudentSet::iterator iter;
for (iter=stuSet.begin(); iter!=stuSet.end(); iter++)
{
cout << "Name: " << (*iter).m_name << "Score: " << (*iter).m_score << endl;
}
std::cout << "Hello World!\n";
getchar();
}
運行結果:
2、作爲判別式示例
// functionBool.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
// 刪除符合條件的數值
class RmNum
{
private:
int m_num;
int m_count;
public:
RmNum(int n) :m_num(n), m_count(0)
{
}
bool operator()(int)
{
return ++m_count == m_num;
}
};
// 打印
void myPrintf(list<int>& lt)
{
list<int>::iterator it;
for (it = lt.begin(); it != lt.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
cout << "----------------仿函數作爲判別式使用--------------" << endl;
cout << "----------------list中插入數值--------------" << endl;
list<int> tmpList;
for (int i = 0; i < 9; i++)
{
tmpList.emplace_back(i);
}
cout << "----------------打印list中插入的數值--------------" << endl;
myPrintf(tmpList);
cout << "----------------刪除list中符合條件的數值--------------" << endl;
list<int>::iterator pos;
pos = remove_if(tmpList.begin(), tmpList.end(), RmNum(2));
tmpList.erase(pos, tmpList.end());
cout << "----------------打印刪除後list中的數值--------------" << endl;
myPrintf(tmpList);
std::cout << "Hello World!\n";
getchar();
}
運行結果:
3、擁有內部狀態示例
// functionState.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include <iostream>
#include <algorithm>
#include <list>
using namespace std;
class mySequence
{
private:
int m_value;
public:
mySequence(int ivalue) :m_value(ivalue)
{
}
int operator()()
{
return m_value++;
}
};
void myPrintf(list<int>& lt)
{
list<int>::iterator it;
for (it = lt.begin(); it != lt.end(); it++)
{
cout << *it << " , ";
}
cout << endl;
}
int main()
{
cout << "----------------仿函數擁有內部狀態--------------" << endl;
cout << "----------------list中插入數值--------------" << endl;
list<int> tmpList;
cout << "----------------從1開始序列化list--------------" << endl;
generate_n(back_inserter(tmpList), 9, mySequence(1));
myPrintf(tmpList);
cout << "----------------從10開始序列化list--------------" << endl;
generate(tmpList.begin(), tmpList.end(), mySequence(10));
myPrintf(tmpList);
std::cout << "Hello World!\n";
getchar();
}
運行結果:
4、作爲算法for_each的返回值示例
// functionForEach.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class AverageValue
{
private:
int m_num;
int m_sum;
public:
AverageValue() :m_num(0), m_sum(0)
{
}
void operator()(int elem)
{
m_num++;
m_sum += elem;
}
double value()
{
return static_cast<double>(m_sum*1.0 / m_num);
}
};
void myPrintf(vector<int>& v)
{
vector<int>::iterator it;
for (it = v.begin(); it != v.end(); it++)
{
cout << *it << " , ";
}
cout << endl;
}
int main()
{
cout << "----------------仿函數作爲算法for_each的返回值使用--------------" << endl;
vector<int> tmpVector;
cout << "----------------vector中插入數值--------------" << endl;
for (int i=0; i<10; i++)
{
tmpVector.emplace_back(i);
}
cout << "----------------打印vector中插入的數值--------------" << endl;
myPrintf(tmpVector);
cout << "----------------打印vector中插入的數值--------------" << endl;
AverageValue averValue = for_each(tmpVector.begin(), tmpVector.end(), AverageValue());
cout << "AverageValue: " << averValue.value() << endl;
std::cout << "Hello World!\n";
getchar();
}
運行結果:
能力有限,如有錯誤,多多指教!覺得有用,點贊鼓勵一下吧!