C++之TR1::function

Tr1::function的介绍

它是一个类模板,类的成员变量是一个函数指针。可以把它看作一个智能函数指针(和shared_ptr智能指针对比着理解)。

一. 头文件

#include<functional>

二. 使用

01. //t.cpp
02. #include "stdafx.h"
03. #include<iostream>
04. #include<functional>
05. using namespace std;
06. void foo(int i){cout<<"aaa"<<endl;}
07. void (*p)(int)=foo;
08. int _tmain(int argc, _TCHAR* argv[])
09. {
10. function<void (int)> fm;
11. fm=foo;
12. (*p)(2);
13. fm(2);
14. return 0;
15. }

可以看出它和函数指针很像,但是它具有很多函数指针做不到的事情。下面慢慢说。

1. 定义一个function对象。

由于function是一个类模板,所以使用起来,首先定义一个类的对象。

Function <void (int)> fm;-----<>中第一个参数是要绑定函数的返回类型,第二个参数是要绑定的函数的参数列表。注意使用小括号括起来。

2. 像函数指针一样,这个指针需要指向某个函数。

fm=function<void (int)>(foo);

3. 由于类模板function重载了()符号。所以使用起来比函数指针更易用。

Fm(2);

下面说一下为什么要有tr1::function.也就是它相对于函数指针的优点:

1. 绑定的函数的类型

函数指针只能绑定普通的外部函数。而tr1::function可以绑定各种函数类型。

(1) 外部普通函数和类的static函数

01. //t.cpp
02. #include "stdafx.h"
03. #include<iostream>
04. #include<functional>
05. using namespace std;
06. class A{
07. public:
08. static void foo(inti){cout<<"aaa"<<endl;}
09. };
10. int _tmain(int argc, _TCHAR* argv[])
11. {
12. function<void (int)>fm(A::foo);
13. //function<void (int)> fm;fm=function<void(int)>(A::foo); also OK
14. void (*p)(inti)=A::foo();//error
15. fm(2);
16. return 0;
17. }

因为外部函数和类的static很相似,所以使用起来也很相似。

(2)类的非static成员函数。

01. //t.cpp
02. #include "stdafx.h"
03. #include<iostream>
04. #include<functional>
05. using namespace std;
06. class A{
07. public:
08. void foo(int i){cout<<"aaa"<<endl;}
09. };
10. int _tmain(int argc, _TCHAR* argv[])
11. {
12. A b;
13. function<void (int)>fm=bind(&A::foo,b,tr1::placeholders::_1);//OK
14. //function<void (int)> fm=b.foo();//error
15. fm(2);
16. return 0;
17. }

注意必须是&A::foo(),这个符号&不能少,这是由function决定的。这里bind中的foo只是接受一个参数,而实际上是需要两个参数,因为static函数是没有对象就存在的,而非static成员函数必须有对象之后才能存在,所以这个成员函数需要指明是哪个对象的成员函数。

(3) 绑定虚函数,呈现多态

01. //t.cpp
02. #include "stdafx.h"
03. #include<iostream>
04. #include<functional>
05. using namespace std;
06. class A{
07. public:
08. virtual void foo(int i){cout<<"A"<<endl;}
09. void fun(){
10. function<void (int)>fm=bind(&A::foo,this,tr1::placeholders::_1);
11. fm(2);//这里和直接调用foo();效果是一样的。并没有改变它的多态性质
12. }
13. };
14. class B:public A
15. {
16. public:void foo(inti){cout<<"B"<<endl;}
17. };
18. int _tmain(int argc, _TCHAR* argv[])
19. {
20. B b;
21. b.fun();
22. return 0;
23. }

其实这里并不是function的什么特殊性质,而只是function是一个普通的类而已,不是因为它而改变多态性质。这里和直接调用foo();的效果一样。

2. 构造函数中的参数

(1) 首先是函数名,这个上面已经讲过

(2) 可以是一个函数对象!(函数对象就是一个重载了操作符”()”的类,这样类的对象可以:a(…);使用起来很像函数,所以叫做函数对象)

01. //t.cpp
02. #include "stdafx.h"
03. #include<iostream>
04. #include<functional>
05. using namespace std;
06. class A{
07. public:
08. void operator()(int i){cout<<"A"<<endl;
09. }
10. void foo(){}
11. };
12. int _tmain(int argc, _TCHAR* argv[])
13. {
14. A a;
15. function<void (int)> fm(a);
16. fm(2);
17. return 0;
18. }

注意这里,居然可以把一个类对象放到function里!这好像违反了function函数指针的原意。但是注意:由于function没有提供返回它拥有的东西的函数,所以这里只能fm(2);来调用类中的重载()函数。不能调用类中的其他函数。所以它还是一个函数指针,只是这个指针指向的函数是一个类中的重载()函数罢了。

3. function类模板的其他几个member函数

(1) assign函数,为这个函数指针分配一个函数实体。

(2) swap函数,交换两个函数指针拥有的东西

(3) target函数,测试本函数指针指向的函数类型是不是为指定类型

(4) target_type函数,获取函数指针指向的函数的类型信息

不常用,也不好用,所以了解即可。

总结:其实function和函数指针很像,只是比函数指针能多指向一些特别的函数而已。

普通函数指针只能指向普通的外部函数

Function可以指向:外部函数,类的static函数,类的非static函数,类的virtual函数,类的对象(函数对象)。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值