C++之TR1::function
Tr1::function的介紹
它是一個類模板,類的成員變量是一個函數指針。可以把它看作一個智能函數指針(和shared_ptr智能指針對比著理解)。
一. 頭文件
#include<functional>
二. 使用
view sourceprint? 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函數
view sourceprint? 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成員函數。
view sourceprint? 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) 綁定虛函數,呈現多態
view sourceprint? 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(…);使用起來很像函數,所以叫做函數對象)
view sourceprint? 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函數,類的對象(函數對象)。
總結
以上是生活随笔為你收集整理的C++之TR1::function的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: shared_ptr智能指针源码剖析
- 下一篇: C++编程常见问题—error: pas