C++高级开发之可调用对象、function、bind(1)

简介: 可调用对象  以前函数调用总是离不开一堆圆括号,没错“()”就是函数调用的一个明显标记,这个 “()”有一个称呼叫函数调用运算符。

可调用对象

       07e2320bb649465785e379d4b78237ed.png                        

以前函数调用总是离不开一堆圆括号,没错“()”就是函数调用的一个明显标记,这个 “()”有一个称呼叫函数调用运算符

那么在类中重载了这个函数调用运算符“()”,就可以像使用函数一样是用那个该类的对象,或者换句话说就可以像函数调用一样来“调用”该类的对象

1.函数指针

  创建一个.cpp文件然后加入以下代码

void myfunc(int tv)
{
  cout << "myfunc()函数执行了,tv=" << tv << endl;
}

 在 main函数中加入如下代码

  void(*pmf)(int) = myfunc;
  pmf(20);

07e2320bb649465785e379d4b78237ed.png

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

  仿函数的定义:仿函数又称为函数对象,是一个能行使函数功能的类所定义的对象。防寒输得语法几乎和普通的函数调用一样。

  在 cpp文件前面增加如下 TC类定义

class TC
{
public:
  void operator()(int tv)
  {
    cout << " TC::operator()执行了,tv=" << tv << endl;
  }
};

 在main函数中加入如下代码(可以选择将之前的main函数注释掉)

  TC tc;
  tc(20);//调用的是()操作符,这就是个可调用对象。等价于tc.operator()(20);


8eea4d9e58ce47c8bb1c8ec6d0438e04.png

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

  可被转换为函数值指针的类对象也可以叫做 仿函数或函数对象

  在 cpp文件中增加如下 TC2类定义

class TC2
{
public:
  using tfpoint = void(*)(int);
  static void mtsfunc(int tv) //静态成员函数
  {
    cout << "TC2::mysfunc()静态成员函数执行了,tv=" << tv << endl;
  }
  operator tfpoint() { return myfunc; }//类型转换运算符/类型转换函数
};

在main主函数中,加入如下代码

  TC2 tc2;
  tc2(30);

168fed1804104330a69720b236882a4c.png

4.类成员函数指针

  在前面的 TC类中增加一个 public修饰的成员函数和一个成员变量

public:
  void ptfunc(int tv)
  {
    cout << "TC::ptfunc()执行了,tv=" << tv << endl;
  };
  int m_a;

在 main主函数中加入如下代码

  TC tc3;
  void(TC::*myfpoint)(int) = &TC::ptfunc;//类成员函数指针变量 myfpoint定义并被给初值
  (tc3.*myfpoint)(999); //要调用你成员函数,就必须要用到对象 tc3


109006ea54ba4e5e83f1316c3a8bbb01.png

6.总结

  可调用对象首先被看做一个对象。那么有没有一种方法能够把这些可调用对象的调用形式统一起来呢?有,那就是使用 std::function 把这些可调用对象包装起来。

std::function 可调用对象包装器

 要使用这个类模板,在 cpp文件中要添加头文件 #include

 这个蕾姆办理装的是各种可调用对象,比较遗憾的是不能装类成员函数指针。因为类成员函数指针是需要类对象参与才能完成调用的。

  #include 类模板的特点是:**通过指定模板参数,它能够用统一的方式来处理各种可调用对象。

1.绑定普通函数

  在 main 主函数中加入如下代码

        //返回类型(参数列表)
  std::function<void(int)>f1 = myfunc;//绑定一个普通函数,注意<>中的格式
  f1(100);//调用普通函数


19454a10fef2493ea972dce187629d83.png

2绑定类的静态成员函数

  在前面的TC类中增加一个 public修饰的静态成员函数

  static int stcfunc(int tv)
  {
    cout << "TC::stcfunc()静态函数执行了,tv=" << tv << endl;
    return tv;
  }

在 main函数中加入如下代码

            //返回类型(参数列表)
  std::function<int(int)> fs2 = TC::stcfunc;
  fs2(110);

9770ea6c7f684ed99881c7cfe24196b3.png

3绑定仿函数

  在 main函数中,加入如下代码

  TC tc3;
  std::function<void(int)> f3 = tc3;//提示使用了未初始化的局部变量“tc3”,因为类TC里有成员变量没被初始化,需要增加一个构造函数,还应该初始化一下成员变量才好

35fcf8ed32cf404c9b9d8b2964ebade6.png

  在 TC类中增加 public修饰的构造函数并初始化成员变量 m_a

TC()  //构造函数
  {
    m_a = 1;
  }//加入之后不会再报错了

在 main主函数中,继续增加代码

  f3(120); //TC::operator()执行了, tv = 120
  TC2 tc4;
  std::function<void(int)> f4 = tc4;
  f4(150); //TC2::mysfunc()静态成员函数执行了, tv = 150

11f51b8724f244db985c0146b032ba7a.png

4范例演示

在 cpp文件 前面增加如下 CB类和 CT类定义

class CB
{
  std::function<void()> fcallback;
public:
  CB(const std::function<void()>& f) :fcallback(f)
  {
    int i;
    i = 1;
  }
  void runcallback(void)
  {
    fcallback();
  }
};
class CT
{
public: 
  CT()//构造函数
  {
    cout << "CT::CT()执行" << endl;
  }
  CT(const CT&)//拷贝构造函数
  {
    cout << "CT::CT(const CT&)执行" << endl;
  }
  ~CT()
  {
    cout << "CT::~CT()执行" << endl;
  }
  void operator()(void)
  {
    cout << "CT::opertor()执行" << endl;
  }
};

在 main函数中,加入如下代码:

  CT ct; //可调用对象,这行导致CT构造函数的执行
  CB cb(ct); //cb需要可调用对象做参数来构造,ct因为有operator()所以可以转为const std::function<void (void)> &对象。
           //这行导致CT拷贝构造函数被执行多次
  cb.runcallback(); //CT::opertor()执行

dcf5832e23ed4bf882bb50b29f1a24c0.png

再来一个范例,在 cpp前面增加如下代码

void mycallback(int cs, const std::function<void(int)>& f)
{
  f(cs);
}
void runfunc(int x)
{
  cout << x << endl;
}

在 main中函数中,加入如下代码:

    for (int i = 0; i < 10; i++)
    {
      mycallback(i, runfunc);//0,1,2,3,4,5,6,7,8,9
    }

a56c02d94b9f4222a61853b09af5e7c8.png

从范例中可以看出 std::function 的灵活性非常高,能容纳的可调用对象种类也非常多。

C++高级开发之可调用对象、function、bind(2)https://developer.aliyun.com/article/1415895?spm=a2c6h.13148508.setting.24.16254f0exsfwiz

目录
相关文章
|
2月前
|
机器学习/深度学习 算法 算法框架/工具
为什么使用C++进行机器学习开发
C++作为一种高性能语言,在某些性能要求极高或资源受限的场景下也具有非常重要的地位。C++的高效性和对底层硬件的控制能力,使其在大规模机器学习系统中发挥重要作用,尤其是当需要处理大数据或实时响应的系统时。
47 3
WK
|
20天前
|
机器学习/深度学习 人工智能 算法
那C++适合开发哪些项目
C++ 是一种功能强大、应用广泛的编程语言,适合开发多种类型的项目。它在游戏开发、操作系统、嵌入式系统、科学计算、金融、图形图像处理、数据库管理、网络通信、人工智能、虚拟现实、航空航天等领域都有广泛应用。C++ 以其高性能、内存管理和跨平台兼容性等优势,成为众多开发者的选择。
WK
45 1
|
1月前
|
Rust 资源调度 安全
为什么使用 Rust over C++ 进行 IoT 解决方案开发
为什么使用 Rust over C++ 进行 IoT 解决方案开发
68 7
WK
|
19天前
|
开发框架 移动开发 Java
C++和Java哪个更适合开发移动应用
本文对比了C++和Java在移动应用开发中的优劣,从市场需求、学习难度、开发效率、跨平台性和应用领域等方面进行了详细分析。Java在Android开发中占据优势,而C++则适合对性能要求较高的场景。选择应根据具体需求和个人偏好综合考虑。
WK
38 0
WK
|
20天前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
35 0
|
2月前
|
存储 编译器 调度
C++ 11新特性之bind
C++ 11新特性之bind
34 1
|
1月前
|
NoSQL API Redis
如何使用 C++ 开发 Redis 模块
如何使用 C++ 开发 Redis 模块
|
2月前
|
物联网 C# C语言
物联网开发中C、C++和C#哪个更好用
在物联网(IoT)开发中,C、C++和C#各有优缺点,适用场景不同。C语言性能高、资源占用低,适合内存和计算能力有限的嵌入式系统,但开发复杂度高,易出错。C++支持面向对象编程,性能优秀,适用于复杂应用,但学习曲线陡峭,编译时间长。C#易于学习,与.NET框架结合紧密,适合快速开发Windows应用,但性能略低,平台支持有限。选择语言需根据具体项目需求、复杂性和团队技术栈综合考虑。
|
2月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
136 1
|
1月前
|
C++ 容器
函数对象包装器function和bind机制
函数对象包装器function和bind机制
20 0