51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

C++ 函数对象

函数对象有时也叫仿函数,其本质是一个类对象,由于重载函数调用符号,其可以像普通函一样使用。

  1. 函数调用符号重载语法 {#title-0} ========================
class Demo
{
public:
	// 返回值:由自己来定义
	void operator()()
	{
		cout << "hello world" << endl;
	}
int operator()(int a, int b)
{
	return a + b;
}

};

// 函数调用符号:(), C++支持对该运算符重载。类重载函数调用符号之后,就可以像普通函数一样调用了。 void test01() { // 1.1 语法 Demo demo1; demo1(); // demo1.operator()() cout << demo1(10, 20) << endl; // demo1.operator()(10, 20) // 函数重载了函数调用符号之后,叫做函数对象,仿函数

// 1.2 函数对象的赋值
Demo demo2 = demo1;
demo2();
demo2(10, 20);

function&lt;void()&gt; demo3 = demo1; demo3(); function&lt;int(int, int)&gt; demo4 = demo1; cout &lt;&lt; demo4(10, 20) &lt;&lt; endl;

}

  1. 函数对象相对于普通函数的优点 {#title-1} ============================

C++中使用函数对象作为函数调用,而不是再使用函数指针。

  1. 函数对象本质是一个类,当调用函数对象时,实际执行的是成员函数。类内定义的函数自动成为内联函数。
  2. 函数对象是有类型的,可以使用类型再定义函数对象出来。但是,普通函数是没有类型,无法再创建出来函数。
  3. 函数对象本质上一个类,所以,其可以拥有成员,具有更加丰富表现能力。而普通函数不行: 统计函数调用次数
int cnt = 0;
void func()
{
	++cnt;
}

class Functor { public: Functor() { m_cnt = 0; }

void operator()()
{
	++m_cnt;
	show();
}

void show() {

}

public: int m_cnt; };

  1. lambda 和 函数对象 {#title-2} ===========================

lambda 是匿名的函数对象,本质上也是一个类对象,并不是简单的匿名普通函数。

void test02()
{
	auto f = []() {};
	cout << typeid(f).name() << endl;
auto f1 = [](int a, int b) { cout &lt;&lt; a &lt;&lt; &quot; &quot; &lt;&lt; b &lt;&lt; endl; };
/*
	class 随机名字
	{
	public:
		void operator()(int a, int b) const
		{
			cout &lt;&lt; a &lt;&lt; &quot; &quot; &lt;&lt; b &lt;&lt; endl;
		}
	}
随机名字 对象;

*/

int num1 = 100; int num2 = 200; auto f2 = = mutable { num1 = 100; }; // lambda 表达式默认进行值捕获的时候,是无法修改,原因就是 operator() 函数是用 const 修饰 /* class 随机名字 { public: 随机名字(int a, int b): num1(a), num2(b){} void operator()() const { num1 = 100; } public: mutable int num1; mutable int num2; } */

auto f3 = &amp; { num1 = 100; }; /* class 随机名字 { public: 随机名字(): num1(num1), num2(num2){} void operator()() const { num1 = 100; } public: int &amp;num1; int &amp;num2; } */

auto ff1 = = {}; function&lt;void()&gt; ff2 = = {};

// 下面这种方式无法进行外部变量捕获 // 如果 lambda 捕获外部变量,则其必须以对象的形式存在。 // 如果 Lambda 不捕获外部变量,该对象仅仅是独立可以运行的成员函数。 void(ff3)() = {}; / class 随机名字 { public: void operator()() const {

	}
}

*/

}

  1. 函数对象使用举例 {#title-3} ======================
struct MyCompare
{
	bool operator()(int num1, int num2)
	{
		return num1 > num2;
	}
};

void test03() { // C 语言中使用 qsort 函数排序 // C++ 中使用 sort 函数排序

int arr[] = { 9, 2, 1, 8, 4, 6, 5 };

for (auto val : arr) { cout &lt;&lt; val &lt;&lt; &quot; &quot;; } cout &lt;&lt; endl;

// sort 函数前两个参数是一个区间,第一个元素的位置,最后一个元素的下一个位置 sort(arr, &amp;arr[6] + 1, MyCompare());

for (auto val : arr) { cout &lt;&lt; val &lt;&lt; &quot; &quot;; } cout &lt;&lt; endl;

}

赞(7)
未经允许不得转载:工具盒子 » C++ 函数对象