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

運行結果:
在這裏插入圖片描述
能力有限,如有錯誤,多多指教!覺得有用,點贊鼓勵一下吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章