最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++函數(shù)對(duì)象詳解附帶實(shí)例

 更新時(shí)間:2021年03月04日 11:40:57   投稿:zx  
這篇文章主要介紹了C++函數(shù)對(duì)象詳解附帶實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

如果一個(gè)類將()運(yùn)算符重載為成員函數(shù),這個(gè)類就稱為函數(shù)對(duì)象類,這個(gè)類的對(duì)象就是函數(shù)對(duì)象。函數(shù)對(duì)象是一個(gè)對(duì)象,但是使用的形式看起來(lái)像函數(shù)調(diào)用,實(shí)際上也執(zhí)行了函數(shù)調(diào)用,因而得名。

下面是一個(gè)函數(shù)對(duì)象的例子。

#include <iostream>
using namespace std;
class CAverage
{
public:
  double operator()(int a1, int a2, int a3)
  { //重載()運(yùn)算符
    return (double)(a1 + a2 + a3) / 3;
  }
};
int main()
{
  CAverage average; //能夠求三個(gè)整數(shù)平均數(shù)的函數(shù)對(duì)象
  cout << average(3, 2, 3); //等價(jià)于 cout << average.operator(3, 2, 3);
  return 0;
}

程序的輸出結(jié)果是:
2. 66667

()是目數(shù)不限的運(yùn)算符,因此重載為成員函數(shù)時(shí),有多少個(gè)參數(shù)都可以。

average 是一個(gè)對(duì)象,average(3, 2, 3) 實(shí)際上就是 average.operator(3, 2, 3),這使得 average 看上去像函數(shù)的名字,故稱其為函數(shù)對(duì)象。

函數(shù)對(duì)象應(yīng)用實(shí)例1:在 accumulate 算法中的應(yīng)用

STL 中有以下實(shí)現(xiàn)“累加”功能的算法(函數(shù)模板):

template <class InIt, class T, class Pred>
T accumulate(InIt first, InIt last, T val, Pred op);

該模板的功能是對(duì) [first, last) 中的每個(gè)迭代器 I 執(zhí)行 val = op(val, *I),返回最終的 val。在 Dev C++ 中,numeric 頭文件中 accumulate 的源代碼如下:

template <class InIt, class T, class Pred>
T accumulate(InIt first, Init last, T init, Pred op)
{
  for (; first != last; ++first)
    init = op(init, *first);
  return init;
};

此模板被實(shí)例化后,op(init, *first)必須要有定義,則 op 只能是函數(shù)指針或者函數(shù)對(duì)象。因此調(diào)用該 accmulate 模板時(shí),形參 op 對(duì)應(yīng)的實(shí)參只能是函數(shù)名、函數(shù)指針或者函數(shù)對(duì)象。

下面的程序通過(guò) accumulate 模板求一個(gè) vector 中元素的平方和,其中用到了函數(shù)對(duì)象。

#include <iostream>
#include <vector>
#include <numeric> //accumulate 在此頭文件定義
using namespace std;
template <class T>
void PrintInterval(T first, T last)
{ //輸出區(qū)間[first,last)中的元素
  for (; first != last; ++first)
    cout << *first << " ";
  cout << endl;
}
int SumSquares(int total, int value)
{
  return total + value * value;
}
template<class T>
class SumPowers
{
private:
  int power;
public:
  SumPowers(int p) :power(p) { }
  const T operator() (const T & total, const T & value)
  { //計(jì)算 value的power次方,加到total上
    T v = value;
    for (int i = 0; i < power - 1; ++i)
      v = v * value;
    return total + v;
  }
};
int main()
{
  const int SIZE = 10;
  int a1[] = { 1,2,3,4,5,6,7,8,9,10 };
  vector<int> v(a1, a1 + SIZE);
  cout << "1) "; PrintInterval(v.begin(), v.end());
  int result = accumulate(v.begin(), v.end(), 0, SumSquares);
  cout << "2) 平方和:" << result << endl;
  result = accumulate(v.begin(), v.end(), 0, SumPowers<int>(3));
  cout << "3) 立方和:" << result << endl;
  result = accumulate(v.begin(), v.end(), 0, SumPowers<int>(4));
  cout << "4) 4次方和:" << result;
  return 0;
}

程序的輸出結(jié)果如下:
1)1 2 3 4 5 6 7 8 9 10
2)平方和:385
3)立方和3025
4)4次方和:25333

第 37 行,第四個(gè)參數(shù)是 SumSquares 函數(shù)的名字。函數(shù)名字的類型是函數(shù)指針,因此本行將 accumulate 模板實(shí)例化后得到的模板函數(shù)定義如下:

int accumulate(vector <int>::iterator first, vector <int>::iterator last, int init, int(*op)(int, int))
{
  for (; first != last; ++first)
    init = op(init, *first);
  return init;
}

形參 op 是一個(gè)函數(shù)指針,而op(init, *first)就調(diào)用了指針 op 指向的函數(shù),在第 37 行的情況下就是函數(shù) SumSquares。

第 39 行,第四個(gè)參數(shù)是 SumPowers<int>(3)。SumPowers 是類模板的名字,SumPowers<int> 就是類的名字。類的名字后面跟著構(gòu)造函數(shù)的參數(shù)列表,就代表一個(gè)臨時(shí)對(duì)象。因此 SumPowers<int>(3) 就是一個(gè) SumPowers<int> 類的臨時(shí)對(duì)象。

編譯器在編譯此行時(shí),會(huì)將 accumulate 模板實(shí)例化成以下函數(shù):

int accumulate(vector<int>::iterator first, vector<int>::iterator last, int init, SumPowers<int> op)
{
  for (; first != last; ++first)
    init = op(init, *first);
  return init;
}

形參 op 是一個(gè)函數(shù)對(duì)象,而op(init, *first)等價(jià)于:

op.operator()(init, *first);

即調(diào)用了 SumPowers<int> 類的 operator() 成員函數(shù)。

對(duì)比 SumPowers 和 SumSquares 可以發(fā)現(xiàn),函數(shù)對(duì)象的 operator() 成員函數(shù)可以根據(jù)對(duì)象內(nèi)部的不同狀態(tài)執(zhí)行不同操作,而普通函數(shù)就無(wú)法做到這一點(diǎn)。因此函數(shù)對(duì)象的功能比普通函數(shù)更強(qiáng)大。

函數(shù)對(duì)象應(yīng)用實(shí)例2:在sort算法中的應(yīng)用

STL 中的排序模板 sort 能將區(qū)間從小到大排序。sort 算法有兩個(gè)版本。第一個(gè)版本的原型如下:

template <class_Randlt>
void sort(_Randlt first, _RandIt last);

該模板可以用來(lái)將區(qū)間 [first, last) 中的元素從小到大排序,要求 first、last 是隨機(jī)訪問(wèn)迭代器。元素比較大小是用<進(jìn)行的。如果表達(dá)式a<b的值為 true,則 a 排在 b 前面;如果a<b的值為 false,則 b 未必排在 a 前面,還要看b<a是否成立,成立的話 b 才排在 a 前面。要使用這個(gè)版本的 sort 算法,待排序的對(duì)象必須能用<運(yùn)算符進(jìn)行比較。

sort 算法第二個(gè)版本的原型如下:

template <class_Randlt, class Pred>
void sort(_Randlt first, _RandIt last, Pred op);

這個(gè)版本和第一個(gè)版本的差別在于,元素 a、b 比較大小是通過(guò)表達(dá)式op(a, b)進(jìn)行的。如果該表達(dá)式的值為 true,則 a 比 b ??;如果該表達(dá)式的值為 false,也不能認(rèn)為 b 比 a 小,還要看op(b, a)的值。總之,op 定義了元素比較大小的規(guī)則。下面是一個(gè)使用 sort 算法的例子。

#include <iostream>
#include <algorithm> //sort算法在此頭文件中定義
using namespace std;
template <class T>
void Printlnterva1(T first, T last)
{ //用以輸出 [first, last) 區(qū)間中的元素
  for (; first != last; ++first)
    cout << *first << " ";
  cout << endl;
}
class A
{
public:
  int v;
  A(int n) : v(n) {}
};
bool operator < (const A & a1, const A & a2)
{ //重載為 A 的 const 成員函數(shù)也可以,重載為非 const 成員函數(shù)在某些編譯器上會(huì)出錯(cuò)
  return a1.v < a2.v;
}
bool GreaterA(const A & a1, const A & a2)
{ //v值大的元素作為較小的數(shù)
  return a1.v > a2.v;
}
struct LessA
{
  bool operator() (const A & a1, const A & a2)
  { //v的個(gè)位數(shù)小的元素就作為較小的數(shù)
    return (a1.v % 10) < (a2.v % 10);
  }
};
ostream & operator << (ostream & o, const A & a)
{
  o << a.v;
  return o;
}
int main()
{
  int a1[4] = { 5, 2, 4, 1 };
  A a2[5] = { 13, 12, 9, 8, 16 };
  sort(a1, a1 + 4);
  cout << "1)"; Printlnterva1(a1, a1 + 4); //輸出 1)1 2 4 5
  sort(a2, a2 + 5); //按v的值從小到大排序
  cout << "2)"; Printlnterva1(a2, a2 + 5); //輸出 2)8 9 12 13 16
  sort(a2, a2 + 5, GreaterA); //按v的值從大到小排序
  cout << "3)"; Printlnterva1(a2, a2 + 5); //輸出 3)16 13 12 9 8
  sort(a2, a2 + 5, LessA()); //按v的個(gè)位數(shù)從小到大排序
  cout << "4)"; Printlnterva1(a2, a2 + 5); //輸出 4)12 13 16 8 9
  return 0;
}

編譯至第 45 行時(shí),編譯器將 sort 實(shí)例化得到的函數(shù)原型如下:

void sort(A* first, A* last, bool (*op)(const A &, const A &) );

該函數(shù)在執(zhí)行過(guò)程中,當(dāng)要比較兩個(gè)元素 a、b 的大小時(shí),就是看 op(a, b) 和 op(b, a) 的返回值。本程序中 op 指向 GreaterA,因此就用 GreaterA 定義的規(guī)則來(lái)比較大小。

編譯至第 47 行時(shí),編譯器將 sort 實(shí)例化得到的函數(shù)原型如下:

void sort( A* first, A* last, LessA op);

該函數(shù)在執(zhí)行過(guò)程中,當(dāng)要比較兩個(gè)元素 a、b 的大小時(shí),就是看 op(a, b) 和 op(b, a) 的返回值。本程序中,op(a, b) 等價(jià)于 op.opeartor(a, b),因此就用 LessA 定義的規(guī)則來(lái)比較大小。

STL 中定義了一些函數(shù)對(duì)象類模板,都位于頭文件 functional 中。例如,greater 模板的源代碼如下:

template <class T>
struct greater
{
  bool operator()(const T& x, const T& y) const{
    return x > y;
  }
};

假設(shè)有以下數(shù)組:

int a[4] = {3, 5, 34, 8};

要將該數(shù)組從大到小排序,則只需寫:

sort( a, a+4, greater<int>() );

要使用 greater 模板,須確保>運(yùn)算符本來(lái)就有定義,或經(jīng)過(guò)了適當(dāng)?shù)闹剌d。

list 容器的 sort 成員能將元素從小到大排序。它也有兩個(gè)版本:一個(gè)是沒(méi)有參數(shù)的函數(shù),比較大小用<運(yùn)算符;另一個(gè)是函數(shù)模板,原型如下:

template <class Pred>
void sort(Pred op);

sort 函數(shù)允許自定義比較大小的規(guī)則,即 op(x, y) 為真就認(rèn)為 x 比 y 小。例如,假設(shè)有:

list<int> lst;

如果希望將 lst 中的元素按其整數(shù)數(shù)值從大到小排序,只需寫:

lst.sort( greater<int>() );

在使用關(guān)聯(lián)容器和許多算法時(shí),都可以用函數(shù)對(duì)象來(lái)定義比較大小的規(guī)則,以及其他一些規(guī)則和操作。

STL 中的函數(shù)對(duì)象類模板

STL 中有一些函數(shù)對(duì)象類模板,如表 1 所示。

表1:STL 中的函數(shù)對(duì)象類模板

函數(shù)對(duì)象類模板 成員函數(shù) T operator ( const T & x, const T & y) 的功能
plus <T> return x + y;
minus < > return x - y;
multiplies <T> return x * y;
divides <T> return x / y;
modulus <T> return x % y;
  成員函數(shù) bool operator( const T & x, const T & y) 的功能
equal_to <T> return x == y;
not_equal_to <T> return x! = y;
greater <T> return x > y;
less <T> return x < y;
greater_equal <T> return x > = y;
less_equal <T> return x <= y;
logical_and <T> return x && y;
logical_or <T> return x || y;
  成員函數(shù) T operator( const T & x) 的功能
negate <T> return - x;
  成員函數(shù) bool operator( const T & x) 的功能
logical_not <T> return ! x;

例如,如果要求兩個(gè) double 型變量 x、y 的乘積,可以寫:

multiplies<double> () (x, y)

less 是 STL 中最常用的函數(shù)對(duì)象類模板,其定義如下:

template <class_Tp>
struct less
{
  bool operator() (const_Tp & __x, const_Tp & __y) const
  { return __x < __y; }
};

要判斷兩個(gè) int 變量 x、y 中 x 是否比 y 小,可以寫:

if( less<int>()(x, y) ) { ... }

引入函數(shù)對(duì)象后 STL 中的“大”、“小”和“相等”概念

前面提到過(guò),默認(rèn)情況下,STL 中的容器和算法比較元素的大小是通過(guò)<運(yùn)算符進(jìn)行的。通過(guò) 10.3.4 節(jié)可知,sort 和 list::sort 都可以通過(guò)一個(gè)函數(shù)對(duì)象或函數(shù)自定義比較元素大小的規(guī)則。例如以下的 sort 版本:

template <class_RandIt, class Pred>
void sort(_RandIt first, _RandIt last, Pred op);

實(shí)際調(diào)用 sort 時(shí),和 op 對(duì)應(yīng)的實(shí)參可以是一個(gè)函數(shù)對(duì)象或者函數(shù)的名字。sort 在執(zhí)行過(guò)程中用 op(x, y) 比較 x 和 y 的大小,因此可以將 op 稱為自定義的“比較器”。

關(guān)聯(lián)容器中的元素是從小到大排序的。使用關(guān)聯(lián)容器時(shí),也可以用自定義的比較器取代<運(yùn)算符,以規(guī)定元素之間的大小關(guān)系。STL 中還有許多算法都可以自定義比較器。在自定義比較器 op 的情況下,以下三種說(shuō)法是等價(jià)的:

  • x 小于 y。
  • op(x, y) 的返回值為 true。
  • y 大于 x。

同樣地,對(duì)關(guān)聯(lián)容器的 find 和 count 成員函數(shù)以及其他一些在有序區(qū)間上的 STL 算法而言,在自定義比較器 op 的情況下,x和y相等與op(x, y)和op(y, x)都為假是等價(jià)的。

到此這篇關(guān)于C++函數(shù)對(duì)象詳解附帶實(shí)例的文章就介紹到這了,更多相關(guān)C++ 函數(shù)對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言使用回溯法解旅行售貨員問(wèn)題與圖的m著色問(wèn)題

    C語(yǔ)言使用回溯法解旅行售貨員問(wèn)題與圖的m著色問(wèn)題

    回溯法即是在按條件搜索走不通的情況下退回再選擇其他路線的方法,這里我們來(lái)看C語(yǔ)言使用回溯法解旅行售貨員問(wèn)題與圖的m著色問(wèn)題的方法示例:
    2016-07-07
  • C++三色球問(wèn)題描述與算法分析

    C++三色球問(wèn)題描述與算法分析

    這篇文章主要介紹了C++三色球問(wèn)題描述與算法分析,結(jié)合注釋形式詳細(xì)講述了三色球問(wèn)題的描述與相應(yīng)的算法設(shè)計(jì)思路,并給出了相關(guān)的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2016-05-05
  • C++無(wú)法重載點(diǎn)符號(hào)、::、sizeof等的原因

    C++無(wú)法重載點(diǎn)符號(hào)、::、sizeof等的原因

    這篇文章主要介紹了C++無(wú)法重載點(diǎn)符號(hào)、::、sizeof等的原因的相關(guān)資料,需要的朋友可以參考下
    2016-05-05
  • 詳解C++編程中對(duì)二進(jìn)制文件的讀寫操作

    詳解C++編程中對(duì)二進(jìn)制文件的讀寫操作

    這篇文章主要介紹了C++編程中對(duì)二進(jìn)制文件的讀寫操作,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • C++深入分析講解鏈表

    C++深入分析講解鏈表

    當(dāng)我們?cè)趯懸欢未a時(shí),如果要頻繁的在一塊區(qū)域進(jìn)行插入或者刪除操作時(shí),會(huì)發(fā)現(xiàn)用數(shù)組實(shí)現(xiàn)會(huì)比較復(fù)雜,這時(shí)候我們就要用另一種數(shù)據(jù)結(jié)構(gòu),鏈表來(lái)實(shí)現(xiàn)
    2022-06-06
  • 如何利用Matlab繪制出好看的火山圖

    如何利用Matlab繪制出好看的火山圖

    火山圖是散點(diǎn)圖的一種,它將統(tǒng)計(jì)測(cè)試中的統(tǒng)計(jì)顯著性量度和變化幅度相結(jié)合,從而能夠幫助快速直觀地識(shí)別那些變化幅度較大且具有統(tǒng)計(jì)學(xué)意義的數(shù)據(jù)點(diǎn)。本文將通過(guò)Matlab繪制好看的火山圖,需要的可以參考一下
    2022-03-03
  • C++深入講解引用的特點(diǎn)及與指針的區(qū)別

    C++深入講解引用的特點(diǎn)及與指針的區(qū)別

    引用是C++一個(gè)很重要的特性,顧名思義是某一個(gè)變量或?qū)ο蟮膭e名,對(duì)引用的操作與對(duì)其所綁定的變量或?qū)ο蟮牟僮魍耆葍r(jià),這篇文章主要給大家總結(jié)介紹了C++中引用的相關(guān)知識(shí)點(diǎn),需要的朋友可以參考下
    2022-05-05
  • VS中scanf函數(shù)報(bào)錯(cuò)問(wèn)題的幾種解決方法

    VS中scanf函數(shù)報(bào)錯(cuò)問(wèn)題的幾種解決方法

    本文主要介紹了VS中scanf函數(shù)報(bào)錯(cuò)問(wèn)題的幾種解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • C/C++ Zlib庫(kù)封裝MyZip壓縮類的詳細(xì)過(guò)程

    C/C++ Zlib庫(kù)封裝MyZip壓縮類的詳細(xì)過(guò)程

    在軟件開發(fā)中,文件的壓縮和解壓縮是一項(xiàng)常見的任務(wù),而ZIP是一種被廣泛應(yīng)用的壓縮格式,本文將聚焦于一個(gè)簡(jiǎn)化的C++實(shí)現(xiàn),通過(guò)分析代碼,我們將深入了解其設(shè)計(jì)和實(shí)現(xiàn)細(xì)節(jié),感興趣的朋友一起看看吧
    2023-11-11

最新評(píng)論

济源市| 平遥县| 香港| 长宁县| 衢州市| 页游| 建昌县| 怀集县| 肇东市| 黎城县| 上林县| 阿克| 青海省| 隆昌县| 旺苍县| 柞水县| 朝阳市| 塔城市| 锡林浩特市| 平谷区| 贞丰县| 临澧县| 清涧县| 玛曲县| 元氏县| 黄骅市| 高青县| 资阳市| 东乡族自治县| 黑河市| 买车| 淮北市| 四平市| 屏南县| 建瓯市| 宜兰县| 松潘县| 宜兴市| 兰西县| 札达县| 宝丰县|