• C++学习笔记(二十九)


    在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第二十九篇博客。

    本篇博客介绍了C++的函数对象。

    本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。

    目录

    函数对象

    函数对象概念

    函数对象使用

    谓词

    算术仿函数

    关系仿函数

    逻辑仿函数


    函数对象

    函数对象概念

    重载函数调用操作符的类,其对象常称为函数对象。函数对象使用重载的()时,行为类似于函数调用,也称为仿函数。函数对象是一个类,不是一个函数。

    函数对象使用

    函数对象在使用时,可以像普通函数那样调用,可以有参数,也可以有返回值。

    函数对象可以有自己的状态,也可以作为参数传递。

    1. #include
    2. using namespace std;
    3. class test
    4. {
    5. public:
    6. int operator()(int a, int b) {
    7. return a + b;
    8. }
    9. };
    10. int main(void)
    11. {
    12. test t;
    13. cout << t(10, 15) << endl;
    14. return 0;
    15. }

    程序的输出是:

    25

    1. #include
    2. #include
    3. using namespace std;
    4. class test
    5. {
    6. public:
    7. int time;
    8. test() {
    9. time = 0;
    10. }
    11. void operator() (string str) {
    12. cout << str << endl;
    13. time += 1;
    14. }
    15. };
    16. int main(void)
    17. {
    18. test t;
    19. t("Hello C++");
    20. t("Hello C++");
    21. t("Hello C++");
    22. t("Hello C++");
    23. t("Hello C++");
    24. cout << t.time << endl;
    25. return 0;
    26. }

    test类有成员变量time,构造函数将time的值定为0。重载()接受一个string参数,将其输出,同时time加一。main函数创建了一个test类对象t,调用()五次,并输出随后time的值。

    程序的输出是:

    Hello C++
    Hello C++
    Hello C++
    Hello C++
    Hello C++
    5

    time统计了调用()的次数。

    1. #include
    2. #include
    3. using namespace std;
    4. class test
    5. {
    6. public:
    7. void operator() (string s) {
    8. cout << s << endl;
    9. }
    10. };
    11. void dotest(test& t)
    12. {
    13. t("Hello C++");
    14. }
    15. int main(void)
    16. {
    17. test t;
    18. dotest(t);
    19. return 0;
    20. }


    test类重载了()。main函数创建了一个test类对象t,并将其作为参数传递给dotest函数。dotest函数调用参数的()。

    程序的输出是:

    Hello C++

    谓词

    返回bool类型的仿函数称为谓词。如果接受一个参数,就叫做一元谓词,如果接受两个参数,就叫二元谓词。

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. class test
    6. {
    7. public:
    8. bool operator()(int num) {
    9. return num > 5;
    10. }
    11. };
    12. int main(void)
    13. {
    14. vector<int> v;
    15. int i;
    16. for (i = 1; i <= 10; i += 1) {
    17. v.push_back(i);
    18. }
    19. vector<int>::iterator it = find_if(v.begin(), v.end(), test());
    20. if (it == v.end()) {
    21. cout << "Not found" << endl;
    22. }
    23. else {
    24. cout << "Have found " << *it << endl;
    25. }
    26. return 0;
    27. }

    test函数重载了(),返回参数是否大于5,大于为true,否则为false。main函数创建了一个vector容器,加入1至10。随后使用了find_if算法,该算法在此处返回大于5的第一个元素的迭代器(没有就是.end,但是本例很显然是有的,这个算法后面详细介绍)。随后判断是否找到,找到还会输出其指向元素。

    程序的输出是:

    Have found 6

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. class test
    6. {
    7. public:
    8. bool operator()(int a, int b) {
    9. return a > b;
    10. }
    11. };
    12. int main(void)
    13. {
    14. vector<int> v;
    15. v.push_back(20);
    16. v.push_back(40);
    17. v.push_back(30);
    18. v.push_back(50);
    19. v.push_back(10);
    20. for (vector<int>::iterator it = v.begin(); it != v.end(); it += 1) {
    21. cout << *it << " ";
    22. }
    23. cout << endl;
    24. sort(v.begin(), v.end(), test());
    25. for (vector<int>::iterator it = v.begin(); it != v.end(); it += 1) {
    26. cout << *it << " ";
    27. }
    28. cout << endl;
    29. return 0;
    30. }

    test类重载了(),判断两个参数的大小关系。vector容器加入了五个int类型常量,随后使用了sort进行排序,排序时第三个参数就是test(),因此会降序排序。

    程序的输出是:

    20   40   30   50   10
    50   40   30   20   10

    算术仿函数

    STL内建了一些函数对象,分为算术仿函数,关系仿函数和逻辑仿函数。这些仿函数产生的对象,用法和一般函数完全相同。使用这些函数对象需要包含头文件functional

    算术仿函数实现四则运算,其中negate是一元运算,其他都是二元运算。

    template T plus 是加法仿函数。

    template T minus是减法仿函数。

    template T multiplies是乘法仿函数。

    template T divides是除法仿函数。

    template T modulus是取模仿函数。

    template T negate是取反仿函数。

    1. #include
    2. #include
    3. using namespace std;
    4. int main(void)
    5. {
    6. plus<int> p;
    7. cout << p(10, 15) << endl;
    8. minus<int> m1;
    9. cout << m1(20, 12) << endl;
    10. multiplies<int> m2;
    11. cout << m2(6, 8) << endl;
    12. divides<int> d;
    13. cout << d(20, 7) << endl;
    14. modulus<int> m3;
    15. cout << m3(20,7) << endl;
    16. negate<int> n;
    17. cout << n(10) << endl;
    18. return 0;
    19. }

    程序的输出是:

    25
    8
    48
    2
    6
    -10
     

    关系仿函数

    关系仿函数用于实现关系对比。

    template bool equal_to是等于仿函数。

    template bool not_equal_to是不等于仿函数。

    template bool greater是大于仿函数。

    template bool greater_equal是大于等于仿函数。

    template bool less是小于仿函数。

    template bool less_equal是小于等于仿函数。

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. int main(void)
    7. {
    8. vector<int> v;
    9. v.push_back(20);
    10. v.push_back(30);
    11. v.push_back(40);
    12. v.push_back(10);
    13. v.push_back(50);
    14. sort(v.begin(), v.end(), greater<int>());
    15. for (vector<int>::iterator it = v.begin(); it < v.end(); it += 1) {
    16. cout << *it << " ";
    17. }
    18. cout << endl;
    19. return 0;
    20. }

    sort的第三个参数是greater,因此会进行降序排序。

    程序的输出是:

    50   40   30   20   10

    1. #include
    2. #include
    3. using namespace std;
    4. int main(void)
    5. {
    6. equal_to<int> et;
    7. cout << et(10, 20) << endl;
    8. cout << et(10, 10) << endl;
    9. not_equal_to<int> net;
    10. cout << net(10, 20) << endl;
    11. cout << net(10, 10) << endl;
    12. greater<int> g;
    13. cout << g(10, 0) << endl;
    14. cout << g(10, 10) << endl;
    15. cout << g(10, 15) << endl;
    16. greater_equal<int> ge;
    17. cout << ge(10, 0) << endl;
    18. cout << ge(10, 10) << endl;
    19. cout << ge(10, 15) << endl;
    20. less<int> l;
    21. cout << l(10, 0) << endl;
    22. cout << l(10, 10) << endl;
    23. cout << l(10, 15) << endl;
    24. less_equal<int> le;
    25. cout << le(10, 0) << endl;
    26. cout << le(10, 10) << endl;
    27. cout << le(10, 15) << endl;
    28. return 0;
    29. }

    程序的输出是:

    0
    1
    1
    0
    1
    0
    0
    1
    1
    0
    0
    0
    1
    0
    1
    1
     

    逻辑仿函数

    逻辑仿函数用于实现逻辑运算。

    template bool logical_and是逻辑与仿函数。

    template bool logical_or是逻辑或仿函数。

    template bool logical_not是逻辑非仿函数。

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. int main(void)
    7. {
    8. vector<bool> v1;
    9. v1.push_back(true);
    10. v1.push_back(false);
    11. v1.push_back(true);
    12. v1.push_back(false);
    13. for (vector<bool>::iterator it = v1.begin(); it != v1.end(); ++it) {
    14. cout << *it << " ";
    15. }
    16. cout << endl;
    17. vector<bool> v2;
    18. v2.resize(v1.size());
    19. transform(v1.begin(), v1.end(), v2.begin(), logical_not<bool>());
    20. for (vector<bool>::iterator it = v2.begin(); it != v2.end(); ++it) {
    21. cout << *it << " ";
    22. }
    23. cout << endl;
    24. return 0;
    25. }

    transform将v1的每个元素进行逻辑反运算后赋给v2,此算法后面介绍。

    程序的输出是:

    1   0   1   0
    0   1   0   1

  • 相关阅读:
    某手创作服务 __NS_sig3 sig3 | js 逆向
    一行代码为特定状态绑定SwiftUI视图动画
    linux内核获取本机网卡的统计信息
    模拟vue动态路由
    finally.h
    300行代码模拟cdn
    前端两个重点:性能优化、安全
    C/C++ 课程设计 | 银行管理系统
    数据可视化工具中的显眼包:奥威BI自带方案上阵
    Python高级进阶(1)----深入理解Python迭代器与生成器
  • 原文地址:https://blog.csdn.net/m0_71007572/article/details/126435844