美文网首页
可调用对象

可调用对象

作者: arkliu | 来源:发表于2022-11-11 10:03 被阅读0次

可调用对象分类

  • 函数指针
void fun(int age, string name) {
    cout << "age :"<<age <<"   name:"<<name<<endl;
}

using funptr = void(*)(int,string);
  • 具有operator()成员函数的类对象(防函数)
class AA{
    public:
        void operator()(string name) {
            cout << "AA name:" << name << endl;
        }
};    

int main() {
    AA a;
    a("hello world");
    return 0;
}
  • lambda函数
auto func1 = [](int age, string name) { 
        std::cout << age <<"  "<< name<<std::endl; 
    };
func1(22, "张三");
  • 一个可被转换为函数指针的类对象
void fun(int age, string name) {
    cout << "age :"<<age <<"   name:"<<name<<endl;
}

using funptr = void(*)(int,string);

class AA{
    public:
        void operator()(string name) {
            cout << "AA name:" << name << endl;
        }

        operator funptr() {
            return printAA; // printAA这里必须是static类型
        }

        static void printAA(int age, string name) {
            cout << "age :"<<age <<"   name:"<<name<<endl;
        }
};    

int main() {
    AA a;
    a("hello world");

    AA aa;
    aa(33, "张三");
    return 0;
}
image.png
  • 类函数成员指针或类成员指针
#include<iostream>
#include<string>
#include<typeinfo>
#include <map>
#include <vector>
using namespace std;

void fun(int age, string name) {
    cout << "age :"<<age <<"   name:"<<name<<endl;
}

using funptr = void(*)(int,string);

class AA{
    public:
        int m_age;
        string m_name;
        void operator()(string name) {
            cout << "AA name:" << name << endl;
        }
        // 将类对象转换为函数
        operator funptr() {
            return printAA; // printAA这里必须是static类型
        }

        static void printAA(int age, string name) {
            cout << "printAA age :"<<age <<"   name:"<<name<<endl;
        }

        void fun1(int age ,string name) {
            cout << "fun1 age :"<<age <<"   name:"<<name<<endl;
        }
};    

int main() {
    // 类的函数指针
    funptr ptr1 = AA::printAA;
    using Fptr = void(AA::*)(int age, string name);
    Fptr ptr2 = &AA::fun1;

    AA aa;
    (aa.*ptr2)(33, "李四"); // fun1 age :33   name:李四

    // 类的成员指针
    using FMemberPtr = int AA::*;
    FMemberPtr ptr3 = &AA::m_age;
    aa.m_age = 45;
    cout << "aa.m_age = "<<aa.m_age<< endl; // aa.m_age = 45
    return 0;
}

可调用对象包装器

std::function是可调用对象的包装器,它是一个类模板,可以容纳除了类成员(函数)指针之外的所有可调用对象,
std::function 必须要包含一个叫做 functional 的头文件
语法如下:

#include <functional>
std::function<返回值类型(参数列表)> name= 可调用对象;
#include<iostream>
#include<string>
#include<typeinfo>
#include <map>
#include <vector>
#include<functional>
using namespace std;

void fun(int age, string name) {
    cout << "age :"<<age <<"   name:"<<name<<endl;
}

using funptr = void(*)(int,string);

class AA{
    public:
        int m_age;
        string m_name;
        void operator()(string name) {
            cout << "AA name:" << name << endl;
        }

        operator funptr() {
            return printAA; // printAA这里必须是static类型
        }

        static void printAA(int age, string name) {
            cout << "printAA age :"<<age <<"   name:"<<name<<endl;
        }

        void fun1(int age ,string name) {
            cout << "fun1 age :"<<age <<"   name:"<<name<<endl;
        }
};    

int main() {
    // 1. 包装普通函数
    function<void(int,string)>pfun1 = fun;
    // 2. 包装类的静态函数
    function<void(int,string)>pfun2 = AA::printAA;
    // 3. 包装仿函数
    AA a1;
    function<void(string)>pfun3 = a1;
    // 包装转换为函数指针的对象
    AA a2;
    function<void(int,string)>pfun4 = a2;

    // 包装lambda
    auto lamFun = [](int age, string name) { 
        std::cout << age <<"  "<< name<<std::endl; 
    };
    function<void(int,string)> pfun5 = lamFun;
    
    // 包装类的成员函数
    function<void(AA&, int,string)> pfun6 = &AA::fun1;
    
    //调用
    pfun1(11, "aaa");
    pfun2(22, "bbbb");
    pfun3("cccc");
    pfun4(33, "dddddd");
    pfun5(43, "sdfsdf");
    pfun6(a1, 66, "mmmm");
    return 0;
}
image.png

std::bind

std::bind用来将可调用对象与其参数一起进行绑定。绑定后的结果可以使用std::function进行保存

std::bind语法

// 绑定非类成员函数/变量
auto f = std::bind(可调用对象地址, 绑定的参数);
// 绑定类成员函/变量
auto f = std::bind(类函数/成员地址, 类实例对象地址, 绑定的参数);

bind基本用法

void fun(int age, string name) {
    cout << "age :"<<age <<"   name:"<<name<<endl;
}
int main() {
    function<void(int,string)> fun_bind1 = bind(fun, placeholders::_1, placeholders::_2);
    fun_bind1(12, "王五");

    // 使用bind绑定参数顺序
    function<void(string,int)> fun_bind2 = bind(fun, placeholders::_2, placeholders::_1);
    fun_bind2("王五", 12);

    // 使用bind提前绑定参数, 默认bind绑定参数是值传递,如果要传递引用使用std::ref()处理
    int age = 18;
    // function<void(string)> fun_bind3 = bind(fun, age, placeholders::_1);
    function<void(string)> fun_bind3 = bind(fun, std::ref(age), placeholders::_1);
    age = 30;
    fun_bind3("牛牛牛牛牛");

    // function包装函数参数比bind绑定的函数参数个数多的情况
    function<void(int, string, int)> fun_bind4 = bind(fun, placeholders::_1, placeholders::_2);
    fun_bind4(22, "uuuu", 0);
    return 0;
}
image.png

bind绑定

int main() {
    // 1. 包装普通函数
    auto pfun1 = bind(fun, placeholders::_1, placeholders::_2);
    // 2. 包装类的静态函数
    auto pfun2 = bind(AA::printAA, placeholders::_1, placeholders::_2);
    // 3. 包装仿函数
    AA a1;
    auto pfun3 = bind(a1, placeholders::_1);
    // 包装转换为函数指针的对象
    AA a2;
    function<void(int,string)>pfun4 = bind(a2, placeholders::_1, placeholders::_2);

    // 包装lambda
    auto lamFun = [](int age, string name) { 
        std::cout << age <<"  "<< name<<std::endl; 
    };
    function<void(int,string)> pfun5 = bind(lamFun, placeholders::_1, placeholders::_2);
    
    // 包装类的成员函数, 使用bind直接绑定对象
    function<void(int,string)> pfun6 = bind(&AA::fun1, &a1, placeholders::_1, placeholders::_2);
    
    //调用
    pfun1(11, "aaa");
    pfun2(22, "bbbb");
    pfun3("cccc");
    pfun4(33, "dddddd");
    pfun5(43, "sdfsdf");
    pfun6(66, "mmmm"); // 上面使用bind直接绑定对象,这里使用时候,就不用传递对象了
    return 0;
}
image.png

相关文章

  • 小结-Python-可迭代、迭代器和生成器的区别

    可迭代对象 可迭代对象指的是定义了_ _ iter _ _ 方法的对象,调用该方法会返回一个迭代器对象。 可迭代对...

  • Kotlin 内联函数 apply、let、run、with、a

    Apply 用this代表当前引用对象; 调用其方法时,this可省略; 一定有返回值,且返回值为当前对象 对象可...

  • 7月4日 晴

    1.可扩展性表示对象是否可以扩展,可以调用Object.esExtensible判定对象是否可扩展,Object....

  • 传递消息objc_msgSend

    在OC中,如果像对象传递消息,就会调用动态绑定机制来绝对调用的方法,对象在接收消息时调用的方法则由运行期决定,也可...

  • 迭代器和生成器

    for..of 语句for..of会遍历可迭代的对象,调用对象上的Symbol.iterator方法。 下面是在数...

  • jQuery的动画和jQuery的事件

    1.jquery链式调用 jquery对象的方法会在执行完后返回这个jquery对象,所有jquery对象的方法可...

  • Python 不可变对象

    不可变对象=》可哈希 对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新...

  • Dart学习-类

    使用类成员 对象的成员包括函数和数据(分别是方法和实例变量)。当你调用一个方法时,你在一个对象上调用它:这个方法可...

  • callable 可调用对象

    有call 方法的就是可调用对象 ,并且可以传入参数可像函数一样使用 可调用对象的意义: 在普通情况下,当一个类只...

  • 对象方法和类方法

    -对象方法 +类方法 调用对象方法必须先创建对象,在通过对象来调用。 类方法不依赖对象,使用对象名直接调用。 类方...

网友评论

      本文标题:可调用对象

      本文链接:https://www.haomeiwen.com/subject/pspazrtx.html