首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

STL 仿函數、成員函數與 mem_fun 使用詳解

     編輯:關於VC++

什麼是仿函數

重載 operator() 的結構體或類別,可像函數一樣被呼叫。STL 演算法(如 for_each)與關聯容器(map, set)大量使用仿函數。

基本範例

struct print_obj {
    void operator()(int a) const { cout << a << endl; }
};
vector<int> v = {1,2,3};
for_each(v.begin(), v.end(), print_obj());

mem_fun 將成員函數轉為仿函數

若類別 D 有 void print(),欲對 vector<D*> 每個元素呼叫:

struct D { int num; D(int i=0):num(i) {} void print() { cout << "num=" << num << endl; } };
vector<D*> V;
V.push_back(new D(1));
V.push_back(new D(2));
for_each(V.begin(), V.end(), mem_fun(&D::print));

mem_fun 回傳 mem_fun_t 仿函數物件,內部儲存成員函數指標,operator() 執行 (p->*func)()。

mem_fun_ref 用於物件而非指標

若容器為 vector<D>,改用 mem_fun_ref(&D::print)。

多型虛擬函數綁定

struct B { virtual void print() = 0; };
struct D1 : B { void print() { cout << "D1" << endl; } };
struct D2 : B { void print() { cout << "D2" << endl; } };
vector<B*> V;
V.push_back(new D1); V.push_back(new D2);
for_each(V.begin(), V.end(), mem_fun(&B::print));

透過基類指標呼叫虛擬函數,自動分派到衍生類別實作。

帶參數成員函數:mem_fun1 / mem_fun1_ref

若成員函數有一參數,可用 mem_fun1 綁定,用法類似。

原理探究:查看原始碼

SGI STL stl_function.h 中:

template <class Ret, class Tp>
inline mem_fun_t<Ret,Tp> mem_fun(Ret (Tp::*f)()) {
    return mem_fun_t<Ret,Tp>(f);
}
template <class Ret, class Tp>
struct mem_fun_t : public unary_function<Tp*, Ret> {
    explicit mem_fun_t(Ret (Tp::*pf)()) : _M_f(pf) {}
    Ret operator()(Tp* p) const { return (p->*_M_f)(); }
    Ret (Tp::*_M_f)();
};

理解原理後,靈活運用 mem_fun/mem_fun_ref/mem_fun1 可大幅簡化 STL 程式碼,符合物件導向設計。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved