静态成员函数与回调函数

news2025/4/11 5:37:59

1. 静态成员函数

1.1 静态成员函数调用

如何代码块里的函数get_object_count是静态成员函数,对静态成员函数无论是通过类名还是通过对象或对象指针调用,最终都会被编译器转换为全局非成员函数的调用。例如obj.get_object_count()Point3d::get_object_count()都会被编译器通过名称处理后转化为_ZN7Point3d16get_object_countEv()
c++没有提供静态函数成员时,或想调用类里的一个函数,且此函数并没有使用类的任何数据成员,类似下面第9行的函数num_test,则可以使用((Point3d *) nullptr)->num_test()这样的方式,注意这种方式是将空指针作为this指针传递进成员函数内,所以在这个函数内是不能够访问数据成员的,否则通过空指针调用会引发异常。
因此可以发现,若一个成员函数没有使用任何类非静态函数成员与非静态数据成员,那么这个成员函数是不需要this指针的,因此也就没必要通过一个类对象来调用,所以当然应该把这个成员函数设置为静态的。

class Point3d {
public:
    static int object_count;

    static int get_object_count() {
        return object_count;
    }

    int num_test() {
        return object_count;
    }

private:
    double x{}, y{}, z{};
};

int Point3d::object_count = 10;

double Point3d::magnitude() const { return sqrt(x * x + y * y + z * z); }

double magnitude(const Point3d *ptr);

int main() {
    std::cout << Point3d::get_object_count() << std::endl;
    printf("%p\n", &Point3d::get_object_count);
    std::cout<<((Point3d *) nullptr)->num_test();
    return 0;
}

当然即使采用对象调用静态成员函数,经过编译器的处理最终也是调用一个全局函数,是不会给这个函数传递this指针的。如下所示的第一行的通过类对象调用的方法会在编译器内部转换为3-4行的调用方式,注意虽然这个匿名对象在第4行是没有用的,但是仍然需要生成,因为这个生成有可能会改变程序执行,所以不能直接省略。

if (Point3d().get_object_count() > 1) {}

// (void) Point3d();
// if (Point3d::object_count > 1) {}

1.2 回调函数

回调函数的讲解可以参考,其作用在于对函数的解耦和复用。例如如下的代码就是一个回调函数的例子,调用sort函数的主函数可以被称为起始函数,bubble_sort函数是中间函数,less函数是回调函数。这里只需要一个中间函数就可以实现不同规则的排序,即可以从小到大或从大到小,只需要改变回调函数即可。

using Compare = bool (*)(int, int);

void bubble_sort(std::vector<int> &vec, Compare compare) {
    //冒泡排序
    for (auto i = 0; i < vec.size(); ++i) {
        for (auto j = 1; j < vec.size() - i; ++j) {
            if (compare(vec[j - 1], vec[j])) {
                std::swap(vec[j - 1], vec[j]);
            }
        }
    }
}

bool less(int i, int j) {
    return i > j;
}

int main() {
    std::vector<int> vec{2, 4, 1, 6, 5};
    bubble_sort(vec, less);
    std::for_each(vec.begin(), vec.end(), [](int i) { std::cout << i << " "; });

    return 0;
}

回调函数和成员函数的关系在于:回调函数不能写成成员函数。如下的代码是无法编译执行的,同时第10-11行也是无法执行的,它们的逻辑是一致的:不能通过函数地址直接调用类非静态成员函数,因为这种函数隐含了一个this指针,如果不通过类对象去调用,是无法传递this指针的,会出现缺少参数的错误。
第二种错误理解角度是函数类型不一致,如下编译器报错,也就是说类成员函数testB的实际类型是void(Point3d:: *)(),而传递的函数指针类型为void (*)(),类型不一致,所以无法编译通过,而这个解决办法即是将testB改为static类型,而static的函数类型为void (*)()

Alt

using CallFunc=void (*)();

class backCall {


public:
    void testA(CallFunc callFunc) {
        cout << 1 << endl;
        callFuc();
        // auto f=&backCall::testB;
        // f();
    }

    void testB() {
        cout << 2 << endl;
    }
};


int main() {
    backCall().testA(&backCall::testA);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/19543.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BigDecimal精度丢失问题

浅谈BigDecimal精度丢失问题 文章目录浅谈BigDecimal精度丢失问题一. 简介二. 错误使用三. 原因分析四. 正确使用一. 简介 ​ Java在java.math包中提供的API类BigDecimal&#xff0c;用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数&#…

大数据Kudu(二):Kudu架构

文章目录 Kudu架构 一、​​​​​​​Kudu存储模型及概念 二、​​​​​​​​​​​​​​Kudu table存储原理 Kudu架构 一、​​​​​​​Kudu存储模型及概念 Kudu有自己的数据存储模型&#xff0c;不依赖于HDFS、Hive、HBase其他大数据组件。Kudu有自己的集群&#…

Oracle存储过程入门教程(通俗理解存储过程)

Oracle存储过程入门通俗介绍一、存储过程通俗理解二、创建存储过程基本语法(汇总)三、执行存储过程的方式&#xff08;5种&#xff09;四、网上现有的创建存储过程的两种方式解释&#xff08;看注释&#xff09;五、一些存储过程示例&#xff08;仅供参考&#xff09;六、其他语…

蒸馏+Distilling Knowledge via Knowledge Review论文笔记

文章目录一、前言二、蒸馏1.背景介绍2.知识蒸馏和迁移学习之间的区别3.Hinton提出的知识蒸馏Pipeline4.蒸馏的知识形式5.知识蒸馏的方法三、Distilling Knowledge via Knowledge Review论文笔记1.思想介绍2.Pipeline3.实验结果参考文献一、前言 近期在阅读cvpr 2021的一篇关于蒸…

通过Tomcat / Small Tomcat,如何部署Servlet?(超详细)

目录 基于Tomcat对Servlet进行部署 一、创建项目 二、引入Servlet依赖 三、构建目录结构 四、编写代码 五、打包程序 六、部署程序 七、验证程序 基于Smart Tomcat对Servlet进行部署 第一步&#xff1a;下载Smart Tomcat插件 第二步&#xff1a;进行相关配置 第三步…

【Unity3D】选中物体描边特效

1 前言 描边的难点在于如何检测和识别边缘&#xff0c;当前实现描边特效的方法主要有以下几种&#xff1a; 1&#xff09;基于顶点膨胀的描边方法 在 SubShader 中开 2 个 Pass 渲染通道&#xff0c;第一个 Pass 通道渲染膨胀的顶点&#xff0c;即将顶点坐标沿着法线方向向外扩…

Android BLE HIDS Data ,从问询DB 到写入Android 节点的flow 之一

BLE 的HIDS服务&#xff0c;可以理解为BR/EDR HID在BLE 上的简化版&#xff0c;因BLE的特殊性&#xff0c;BR/EDR HID的部分feature在HIDS 中被移除。 本文将讨论Android 蓝牙BLE 中HIDS 服务如何接收 Data 并写入到Android 节点"/dev/uhid"的flow。----关于Android…

openpowerlink 01

源码地址&#xff1a; https://sourceforge.net/projects/openpowerlink/ 源码目录 qt 源码目录 qt MN 源码 MN是主站的意思 用cmake 构建 qt cmakelists.txt分析 文件 mnobd.cdc&#xff1a; 此文件用于配置 MN 堆栈。它包括MN和所有CN的所有配置数据&#xff0c;包括网…

云安全解决方案安全保障体系框架

安全需求和挑战 从风险管理 的角度讲&#xff0c;主要就是管理资产、威胁、脆弱性和防护措施及其相关关系&#xff0c;最终保障云计算平台的持续安全&#xff0c;以及 其所支撑的业务的安全。 云计算 平台是在传统 IT技术的基础上&#xff0c;增加了一个虚拟化层&#xff0c;并…

[Spring MVC7] 解决Redis乱码前缀问题

最近在做Redis缓存的时候&#xff0c;遇到了一个棘手的问题&#xff0c;简单来说就是项目使用Spring的RedisTemplate进行Redis数据存取操作&#xff0c;实际应用中发现Redis中key和value会出现“无意义”乱码前缀。如果是普通的java程序是没有这个问题。 本文解决Redis乱码问题…

基于Matlab-gui信号系统设计

目 录 1绪论 - 1 - 2系统分析和开发软件概述 - 6 - 2.1 需求分析 - 6 - 2.2系统开发环境和运行环境 - 6 - 2.3 Matlab图形用户界面(GUI) - 6 - 2.4 系统主要目标及功能 - 7 - 2.4.1 系统目标 - 7 - 2.4.2 系统主要功能 - 8 - 3系统软件平台的设计 10 3.1系统整体框图 10 3.2系统…

阿里的三个「价值支点」

历史总是轮回的。 2015年5月&#xff0c;身处低谷的阿里换了掌舵人&#xff0c;张勇由COO升任CEO&#xff0c;随后进行了一轮组织架构调整&#xff0c;并通过新零售、淘宝直播、阿里云等业态为阿里安上未来发展引擎。 当时的阿里市值涨至2000亿美元左右&#xff0c;华尔街投资…

终端天线—11.NFC线圈仿真

NFC线圈单体仿真 NFC线圈主要根据终端设备预留的空间大小&#xff0c;去设计走线宽度和圈数以及面积&#xff0c;NFC单体主要关注其13.56MHz处的电感量大小&#xff0c;以及阻抗的虚部和实部&#xff0c;可以根据ST和NXP芯片的要求去设计。 一、Original model 1.Simulation …

C语言文件操作【详解】

本期介绍&#x1f356; 主要介绍&#xff1a;为什么使用文件&#xff0c;什么是文件&#xff0c;文件的打开和关闭的操作方法&#xff0c;文件的顺序读写于随机读写&#xff0c;文件读取结束的判定&#x1f440;。 文章目录一、为什么使用文件&#x1f356;二、什么是文件&…

React 入门:使用脚手架写一个Hello组件

文章目录本文目标开发前的准备编写主页面 index.html编写外壳组件 App.js编写入口文件 index.js代码组件化开发 Hello 组件开发 Welcome 组件引用组件组件化实现效果样式的模块化提升编码效率本文目标 通过使用脚手架确实让我们很方便的创建一个 React 项目基础代码结构&#…

力扣(LeetCode)11. 盛最多水的容器(C++)

双指针贪心 盛水的面积 长度 \times 左右柱子最低高度 area(r−l)min(height[l],height[r])area (r-l)\times min(height[l],height[r])area(r−l)min(height[l],height[r]) 初始时&#xff0c;我们不知道每个柱子的高度&#xff0c;但是我们可以选取最左侧柱子和最右侧柱子…

期望E与高斯分布的期望

目录 1. 期望定义 2. 期望性质 2.1 用期望定义方差 / 标准差 方差定义 标准差定义 方差的表示——离散型&#xff1a; 方差的表示——连续型&#xff1a; 方差的性质 3. (一元)高斯分布定义 4. (一元)高斯分布的性质 5. 二维随机向量的数学期望E与方差σ 参考 1. …

PyCharm安装部署(一) 百篇文章学PyQT

本文章是百篇文章学PyQT的第一篇&#xff0c;本文讲述如何安装PyCharm IDEA工具&#xff0c;其它工具也可以但是PyCharm 相对来说用的人多大家都认可(方案成熟)&#xff0c;pycharm是一款功能强大的python编辑器&#xff0c;具有跨平台性&#xff0c;本文介绍一下pycharm在wind…

SSM 医院在线挂号系统

SSM 医院在线挂号系统 SSM 医院在线挂号系统 功能介绍 首页 登录注册 图片轮播展示 系统简介 系统公告 医院介绍 医生展示 医院资讯 预约挂号 收藏 评论 在线留言 查看留言 后台管理 登录 管理员管理 修改密码 医院信息管理 医生信息管理 用户权限管理 科室信息管理 预约挂号…

微信小程序如何转云开发

微信小程序云开发&#xff0c;为前端全栈开发提供了很大的便利。本文主要介绍普通的微信小程序如何让转为云开发。 一、建cloudfunction文件夹 cloudfunction文件夹建立在小程序的根目录下。 二、修改 project.config.json配置 在 project.config.json文件中&#xff0c;添加&…