C++:可调用对象包装器

std::function是可调用对象的包装器。它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可调用对象。通过指定它的模板参数,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟执行它们。

下面的实例代码中演示了可调用对象包装器的基本使用方法:

//普通含税
void print(int num, string name) {
    cout << "id:" << num << ",name:" << name << endl;
}
//抽象出对应的函数指针
//类型别名funcPtr,它代表一个指向接受一个int和一个string参数,并返回void的函数的指针
using funcPtr = void (*)(int, string);

//类
class Test {
public:
    //重载()
    void operator()(string msg) {
        cout << "仿函数:" << msg << endl;
    }

    //将类对象转换为函数指针,此处转换的类型为funcPtr
    operator funcPtr() {
        return world;//return要转换的函数指针类型的实际函数地址
    }

    void hello(int a, string s) {//未定义类对象时,此函数不会存在
        cout << "number:" << a << ",name:" << s << endl;
    }

    static void world(int a, string s) {//未定义类对象时,此函数就已经存在
        cout << "number:" << a << ",name:" << s << endl;
    }

    int m_id = 520;
    string m_name = "tom";
};
    //包装普通函数
    //包装的可调用对象的返回值为void,参数列表为int和string,打包后的名字为f2
    function<void(int, string)> f2 = print;
    f2(2, "f2");

    //包装类中的静态函数
    function<void(int, string)> f3 = Test::world;
    f3(3, "f3");

    //包装仿函数
    Test t3;
    function<void(string)> f4 = t3;
    f4("f4");

    //包装转换为函数指针的对象
    Test t4;
    function<void(int, string)> f5 = t4;
    f5(5, "f5");
class A {
public:
    //构造函数参数是一个包装器类型
    A(const function<void(int, string)> &f) : callback(f) {}

    void notify(int id, string name) {
        callback(id, name);
    }

private:
    function<void(int, string)> callback;
};
    A aa(print);
    aa.notify(1, "aa");

    A ab(Test::world);
    ab.notify(2, "ab");

    A ac(t4);
    ac.notify(3, "ac");

完整代码:

#include <iostream>
#include <string>
#include<functional>

using namespace std;

//普通含税
void print(int num, string name) {
    cout << "id:" << num << ",name:" << name << endl;
}
//抽象出对应的函数指针
//类型别名funcPtr,它代表一个指向接受一个int和一个string参数,并返回void的函数的指针
using funcPtr = void (*)(int, string);

//类
class Test {
public:
    //重载()
    void operator()(string msg) {
        cout << "仿函数:" << msg << endl;
    }

    //将类对象转换为函数指针,此处转换的类型为funcPtr
    operator funcPtr() {
        return world;//return要转换的函数指针类型的实际函数地址
    }

    void hello(int a, string s) {//未定义类对象时,此函数不会存在
        cout << "number:" << a << ",name:" << s << endl;
    }

    static void world(int a, string s) {//未定义类对象时,此函数就已经存在
        cout << "number:" << a << ",name:" << s << endl;
    }

    int m_id = 520;
    string m_name = "tom";
};

class A {
public:
    //构造函数参数是一个包装器类型
    A(const function<void(int, string)> &f) : callback(f) {}

    void notify(int id, string name) {
        callback(id, name);
    }

private:
    function<void(int, string)> callback;
};

int main() {
    Test t;
    t("abc");//使用类中重载的()操作符

    Test t1;
    t1(19, "make");//传递了两个参数,因为将t1对象转换为了函数指针,world函数被调用

    //类的函数指针
    funcPtr f = &Test::world;//静态函数
    //定义指向类中非静态函数(hello)的指针
    using fPtr = void (Test::*)(int, string);//Test::*表示属于Test的指针
    fPtr f1 = &Test::hello;

    //类的成员指针(变量)
    using ptr1 = int Test::*;
    ptr1 pt = &Test::m_id;

    Test t2;
    (t2.*f1)(20, "ace");//解引用*f1是一个函数,调用hello函数
    t2.*pt = 100;//解引用*pt是一个int型变量
    cout << "m_id:" << t2.m_id << endl;

    //包装普通函数
    //包装的可调用对象的返回值为void,参数列表为int和string,打包后的名字为f2
    function<void(int, string)> f2 = print;
    f2(2, "f2");

    //包装类中的静态函数
    function<void(int, string)> f3 = Test::world;
    f3(3, "f3");

    //包装仿函数
    Test t3;
    function<void(string)> f4 = t3;
    f4("f4");

    //包装转换为函数指针的对象
    Test t4;
    function<void(int, string)> f5 = t4;
    f5(5, "f5");

    A aa(print);
    aa.notify(1, "aa");

    A ab(Test::world);
    ab.notify(2, "ab");

    A ac(t4);
    ac.notify(3, "ac");

    return 0;
}

通过测试代码可以得到结论:std::function可以将可调用对象进行包装,得到一个统一的格式,包装完成得到的对象相当于一个函数指针,和函数指针的使用方式相同,通过包装器对象就可以完成对包装的函数的调用了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值