自学内容网 自学内容网

C++:可调用对象

在C++中存在“可调用对象”这么一个概念。准确来说,可调用对象有如下几种定义:

1.是一个函数指针

int print(int a, double b)
{
    cout << a << b << endl;
    return 0;
}
// 定义函数指针
int (*func)(int, double) = &print;

2.是一个具有operator()成员函数的类对象(仿函数)

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Test
{
    // ()操作符重载
    void operator()(string msg)
    {
        cout << "msg: " << msg << endl;
    }
};

int main(void)
{
    Test t;
    t("我是要成为海贼王的男人!!!");// 仿函数
    return 0;
}

3.是一个可被转换为函数指针的类对象

#include <iostream>
#include <string>
#include <vector>
using namespace std;

using func_ptr = void(*)(int, string);
struct Test
{
    static void print(int a, string b)
    {
        cout << "name: " << b << ", age: " << a << endl;
    }

    // 将类对象转换为函数指针
    operator func_ptr()
    {
        return print;
    }
};

int main(void)
{
    Test t;
    // 对象转换为函数指针, 并调用
    t(19, "Monkey D. Luffy");

    return 0;
}

4.是一个类成员函数指针或者类成员指针

#include <iostream>
#include <string>
#include <vector>
using namespace std;

struct Test
{
    void print(int a, string b)
    {
        cout << "name: " << b << ", age: " << a << endl;
    }
    int m_num;
};

int main(void)
{
    // 定义类成员函数指针指向类成员函数
    void (Test::*func_ptr)(int, string) = &Test::print;
    // 类成员指针指向类成员变量
    int Test::*obj_ptr = &Test::m_num;

    Test t;
    // 通过类成员函数指针调用类成员函数
    (t.*func_ptr)(19, "Monkey D. Luffy");
    // 通过类成员指针初始化类成员变量
    t.*obj_ptr = 1;
    cout << "number is: " << t.m_num << endl;

    return 0;
}

汇总:

#include <iostream>
#include <string>

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";
};

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;
    return 0;
}

在上面的例子中满足条件的这些可调用对象对应的类型被统称为可调用类型。C++中的可调用类型虽然具有比较统一的操作形式,但定义方式五花八门,这样在我们试图使用统一的方式保存,或者传递一个可调用对象时会十分繁琐。现在,C++11通过提供std::function 和 std::bind统一了可调用对象的各种操作。


原文地址:https://blog.csdn.net/weixin_48833388/article/details/137528669

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!