std::function使用

函数指针

        定义一个函数指针的方法其实跟定义一个普通指针的方法有点类似,对于普通函数和lanbda表达式的话,基本可以直接赋值给你定义的函数指针。

        同一个函数指针 你甚至可以直接赋值,比如代码中注释的那行,效果跟重新定义一个函数指针一样。调用方法也直接是指针名+括号以及参数,而我所定义的函数以及指针都没有参数的,你也可以添加返回值类型以及参数,但指针也需要相对应的改变添加上参数、返回值类型。

        在使用函数指针的时候,你把*换成&也行,但需要一开始就需要初始化,因为都知道引用的时候就需要初始化的。


void test()
{
	std::cout << "hello I am test" << std::endl;
}

int main()
{
	//普通函数
	void (*func)() =test;
	func();

	//lambda表达式
    //func = []() {std::cout << "I am lambda表达式" << std::endl; };
	void(*func2)() = []() {std::cout << "I am lambda表达式" << std::endl; };
	func2();
	return 0;
}

        其中函数指针不能指向仿函数,指向类成员方法时,是可以的,但是需要加上作用域,区分普通函数和类成员函数,函数指针定义时就需要区分好。

使用了&Base::test&Base::test1来获取成员函数和静态函数的地址,并将它们分别赋值给funcfunc2指针

class Base
{
public:

	void test()
	{std::cout << "I am Base::test" << std::endl;}

	static void test1()
	{std::cout << "I am Bass::test1" << std::endl;}
};

int main()
{
	//指向成员普通函数的话 比较麻烦,因为按照正常的话 成员方法调用你是需要实例化一个对象的
    //另外使用成员函数指针时,需要确保使用正确的语法来调用成员函数
	void (Base::*func)() = &Base::test;
	Base ins;
	(ins.*func)();

	//指向静态函数的话就不需要作用域,大概是因为静态函数不属于某一个对象
    //void (Base::*func2)() =&Base::test1;//会报错
	void (*func2)() =&Base::test1;
	func2();
	return 0;
}

从代码中可以发现,在定义函数指针的时候,当你指向的是静态成员函数的话,指针类型好像不需要添加作用域,我试着加上去,发现报错,应该是不允许加的。指针指向成员函数时,需要加上取地址符,不过我发现指向的是静态成员函数的时候,是可以省略掉取地址符的。指向普通成员函数貌似比较麻烦,因为好像你即使定义好了一个指针,但是你还需要实例化一个对象,调用方法有点像是定义的指针属于对象的一个成员方法一样。

有一点需要注意的是。指针嘛,指向变量都是要取地址符的,好像在函数指针这一块也是一样的。

std::function方法

std::function解决了一些缺点,这个方法支持仿函数,跟定义普通函数指针还是有一些相近的。

#include<iostream>
#include<functional>
void test()
{
	std::cout << "I am test" << std::endl;
}
class Base
{
public:
	void test()
	{
		std::cout << "I am Base::test" << std::endl;
	}
	static void test1()
	{
		std::cout << "I am Bass::test1" << std::endl;
	}
};

int main()
{
	//指向普通函数  只需要在<>中初始化好函数类型就行了,前者为返回值类型,()中是所需参数。
	std::function<void(void)>p=test;
	p();
	//类成员方法
	std::function<void(void)> p1 = &Base::test1;//传值的时候 静态成员方法还是一样
	p1();
	Base ins;
	//使用了std::function方法后,发现传值的方式不一样了,std还提供了一个bind方法,直接把
	//成员函数以及实例化对象绑定到一起了,后期调用也不需要那么麻烦了。
	std::function<void(void)> p2 = std::bind(&Base::test, &ins);
	p2();

	//lambda表达式
	//该方法依旧
	std::function<void(void)> p3 = []() {std::cout << "I am lambda" << std::endl; };
	p3();
	return 0;
}

标准库提供std::function方法,用起来确实比简单的函数指针方便很多,特别是在指向类成员方法的时候,直接和实例化的对象绑定,后期调用可以直接使用额,而不需要像函数指针一样麻烦得很,而标准库也提供了一个bind函数给我们用于绑定方法和对象。当然,对象还是需要一开始就实例化好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值