栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STL 笔记(十四):函数对象

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STL 笔记(十四):函数对象

STL 笔记(十四):函数对象 引入
#include 
#include 
#include 

using namespace std;

// 一、函数对象的引入
int Max(int a, int b)
{
    return a > b ? a : b;
}

void fun(int (*pt) (int, int))
{
    cout << pt(520, 250) << endl;
}

void print(int value)
{
    cout << value << ' ';
}

void test1()
{
    // 1.函数指针
    cout << Max(2, 3) << endl;
    int (*pt) (int, int) = Max;
    cout << pt(2, 3) << endl;

    // 2.函数名做参数
    fun(Max);

    // 3.for_each()
    int a[] = {1, 2, 4};
    vector v(a, a + 3);
    for_each(v.begin(), v.end(), print);
}

// 二、将print函数放入类中 - 仿函数
class Test
{
    int s;
public:
    Test(int t = 0)
    {
        s = t;
    }
    void operator()(int value) // print -> 重载()运算符
    {
        s += 1;
        cout << value << ' ';
    }
    void getCount()
    {
        cout << s << endl;
    }
};

void test2()
{
    // 1. 对()的重载
    Test st;
    st(5);      // 函数对象 -- object(parametre)
    Test()(5);  // 临时对象 -- object_type()(parametre)
    // 2. for_each
    int a[] = {1, 2, 4};
    vector v(a, a + 3);
    for_each(v.begin(), v.end(), st);     // 函数对象
    for_each(v.begin(), v.end(), Test()); // 函数对象【临时、无名】

    /// 函数对象:重载了()的类创建的对象 ///

    // 3.for_each的返回值 -> 函数对象
    Test result = for_each(v.begin(), v.end(), Test(10));
    result.getCount();
    for_each(v.begin(), v.end(), Test(10)).getCount(); 
}

int main()
{
    // test1();
    // test2();

    return 0;
}
分类
#include 
#include 
#include 
#include 

using namespace std;



// 求平均数
class Average
{
private:
    double sum;
    int amount;
public:
    Average()
    {
        sum = 0;
        amount = 0;
    }
    void operator()(double num)
    {
        sum += num;
        amount++;
    }
    double getAverage()
    {
        return sum / amount;
    }
};

// 算数
void test1()
{
    plus plobj; // 加
    cout << plobj(3, 4) << endl; // 7

    minus miobj; // 减
    cout << miobj(3, 4) << endl; // -1

    multiplies muobj; // 乘
    cout << muobj(3, 4) << endl; // 12

    divides diobj; // 除
    cout << diobj(3, 4) << endl; // 0

    modulus moobj; // 模
    cout << moobj(3, 4) << endl; // 3

    negate neobj; // 负
    cout << neobj(3) << endl; // -3

    cout << plus()(3, 4) << endl; // 7
    cout << minus()(3, 4) << endl; // -1
    cout << multiplies()(3, 4) << endl; // 12
    cout << divides()(3, 4) << endl; // 0
    cout << modulus()(3, 4) << endl; // 3
    cout << negate()(3) << endl; // -3
}

// 关系
void test2()
{
    // equal_to // 等于
    // not_equal_to // 不等于
    // greater // 大于
    // less // 小于
    // greater_equal // 大于等于
    // less_equal // 小于等于
}

// 逻辑
void test3()
{
    // logical_and // 逻辑与
    // logical_or  // 逻辑或
    // logical_not // 逻辑非
}

class Complex
{
private:
    int real;
    int virt;
public:
    Complex(int r = 0, int v = 0)
    {
        real = r;
        virt = v;
    }
    void show()
    {
        cout << real << " + " << virt << "i" << endl;
    }
    Complex operator+(Complex c) const // 在调用时主调与被调对象都被转换为了常对象(只能调用常函数)
    {
        return Complex(real + c.real, virt +c.virt);
    }
    bool operator>=(Complex c) const
    {
        if (real > c.real) {
            return true;
        }
        if (real == c.real && virt >= c.virt) {
            return true;
        }
        return false;
    }
};

void test4()
{
    Complex c1(5, 6), c2(7, 8);
    Complex res = plus()(c1, c2);
    res.show();
    cout << greater_equal()(c1, c2) << endl;
}

int main()
{

    /// 求平均数

    // double a[] = {7.0, 8.0, 9.0};
    // vector v(a, a + 3);

    // Average res = for_each(v.begin(), v.end(), Average());

    // cout << res.getAverage() << endl;

    /// 系统提供的仿函数

    // test1(); // 算数
    // test2(); // 关系
    // test3(); // 逻辑

    /// 复数类
    // test4(); // 复数

    return 0;
}
应用
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

class Student
{
private:
    int sNo;
    string sName;
public:
    Student(int a, string b):sNo(a), sName(b) {}
    bool operator>(Student s) const
    {
        return sNo > s.sNo;
    }
    bool operator<(Student s) const
    {
        return sNo < s.sNo;
    }
    void show() const
    {
        cout << sNo << 't' << sName << endl;
    }
    int getSno()
    {
        return sNo;
    }//
    friend ostream & operator<<(ostream & os, Student s) {
        os << s.sNo << 't' << s.sName;
        return os;
    }
};

class MyGreaterBySno
{
public:
    bool operator()(Student s1, Student s2)
    {
        return s1.getSno() > s2.getSno();
    }
};

class ShowInfo
{
public:
    void operator()(Student s)
    {
        s.show();
    }
};

int main()
{
    /// 仿函数的应用

    Student s[] = {
        Student(1001, "Reyn"),
        Student(1002, "Lily")
    };

    // 按照学号大小,从大到小存放学生信息
    // 1. greater
    set > s1(s, s + 2);
    // 2. 仿函数
    set s2(s, s + 2);

    // 输出数据
    // 1. 递推 + 迭代器
    for (set::iterator it = s1.begin(); it != s1.end(); it++) {
        it->show();
    }
    cout << endl;
    for (set::iterator it = s2.begin(); it != s2.end(); it++) {
        it->show();
    }
    cout << endl;

    // 2. for_each + 仿函数
    for_each(s1.begin(), s1.end(), ShowInfo());
    cout << endl;
    for_each(s2.begin(), s2.end(), ShowInfo());
    cout << endl;

    // 3. copy + 重载<<
    copy(s1.begin(), s1.end(), ostream_iterator(cout, "n"));
    cout << endl;
    copy(s2.begin(), s2.end(), ostream_iterator(cout, "n"));
    cout << endl;

    return 0;
}
适配器
#include 
#include 
#include 
#include 
#include 

#define PI 3.14

// 仿函数基类:仿函数适配器中的函数对象必须继承基类
// 1. 一元函数基类:unary_function<_Input, _Output>
// 2. 二元函数基类:binary_function<_Input, _Input, _Output>



using namespace std;



void test1()
{
    int a[] = {4, 5, 6, 7, 8, 9};
    vector v(a, a + 6);
    // 统计顺序表中5大于元素值的个数
    cout << count_if(v.begin(), v.end(), bind1st(greater(), 5)) << endl; // 1
    // 统计顺序表中元素值大于5的个数
    cout << count_if(v.begin(), v.end(), bind2nd(greater(), 5)) << endl; // 4
}

class MyGreater:public binary_function
{
public:
    bool operator()(int x, int y) const
    {
        return x > y;
    }
};

void test2()
{
    int a[] = {4, 5, 6, 7, 8, 9};
    vector v(a, a + 6);
    // 统计顺序表中5大于元素值的个数
    cout << count_if(v.begin(), v.end(), bind1st(MyGreater(), 5)) << endl; // 1
    //
}

class greaterEqual
{
public:
    bool operator()(int x, int y)
    {
        return x >= y;
    }
};

class notGreaterEqual : public binary_function
{
public:
    bool operator()(int x, int y) const
    {
        return x < y;
    }
};

void test3()
{
    int a[] = {5, 4, 7, 6, 8};
    vector v(a, a + 5);

    cout << count_if(v.begin(), v.end(), not1(bind2nd(greater(), 5))) << endl;
    cout << count_if(v.begin(), v.end(), bind2nd(not2(greater()), 5)) << endl;

    sort(v.begin(), v.end(), not2(greater()));
    copy(v.begin(), v.end(), ostream_iterator(cout, " "));
    cout << endl;

    // 降序排列
    sort(v.begin(), v.end(), greaterEqual());
    copy(v.begin(), v.end(), ostream_iterator(cout, " "));
    cout << endl;
    sort(v.begin(), v.end(), not2(notGreaterEqual()));
    copy(v.begin(), v.end(), ostream_iterator(cout, " "));
}

class Student
{
private:
    int sNo;
public:
    Student(int n)
    {
        sNo = n;
    }
    void show()
    {
        cout << sNo << endl;
    }
};

void test4()
{
    Student s[] = {Student(1001), Student(1002)};
    vector v(s, s + 2);

    for_each(v.begin(), v.end(), mem_fun_ref(Student::show));

    vector x;
    x.push_back(&s[0]);
    x.push_back(&s[1]);

    for_each(x.begin(), x.end(), mem_fun(Student::show));
}

void print(int n, string s)
{
    cout << n << ' ' << s << endl;
}

void test5()
{
    int a[] = {5, 4, 7, 6, 8};
    vector v(a, a + 5);

    for_each(v.begin(), v.end(), bind2nd(ptr_fun(print), "Spider Men"));
}



 class Shape // 抽象类
 {
 public:
    virtual void getArea() // 虚函数
    {

    }
 };

 class Circle : public Shape
 {
 private:
    double radius;
 public:
     Circle(double r)
     {
         radius = r;
     }
    void getArea()
    {
        cout << PI * radius * radius << endl; // 宏定义 PI
    }
 };

 class Rectangle : public Shape
 {
     double length;
     double width;
 public:
    Rectangle(double l, double w)
    {
        length = l;
        width = w;
    }
    void getArea()
    {
        cout << length * width << endl;
    }
 };

int main()
{
    /// 仿函数的基类、适配器取反、成员函数、普通函数适配器
    // test1();
    // test2();
    // test3();
    // test4();
    // test5();

    /// 案例 - 求圆和长方形的面积
    Circle c(5.18);
    Rectangle r(5.2, 0.1314);

    vector v; // 多态:虚函数 + 指针
    v.push_back(&c);
    v.push_back(&r);

    for_each(v.begin(), v.end(), mem_fun(Shape::getArea));

    return 0;
}

在下一篇文章,我们将介绍 C++ 中的非变异算法

后记

此文章主要用来作为课程学习过程中的总结,大家如果有什么问题也可以在评论区留言,我会尽力帮大家解决问题,如果觉得对大家有帮助的话,希望多多点赞、转发,谢谢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021967.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号