C++结构体初始化与成员函数实现语法详解

C++结构体初始化与成员函数实现语法详解

一、结构体静态成员初始化语法

在C++中,静态成员变量需要在类外部进行定义和初始化。提供的代码展示了如何为MAIN_PROPULSION_CAN类的静态成员变量进行初始化:

MAIN_PROPULSION_CAN::VoltageThresholds MAIN_PROPULSION_CAN::currentVoltageThresholds = {0, 800, 750  // 0-800V, 高电压阈值750V
};

语法解析:

  1. MAIN_PROPULSION_CAN::VoltageThresholds - 完全限定类型名,表示属于MAIN_PROPULSION_CAN类的VoltageThresholds类型
  2. MAIN_PROPULSION_CAN::currentVoltageThresholds - 静态成员变量的完全限定名
  3. = {0, 800, 750} - 使用初始化列表对结构体成员进行初始化

这种初始化方式称为"聚合初始化",适用于简单的结构体类型。C++11以后也可以使用统一初始化语法:

MAIN_PROPULSION_CAN::VoltageThresholds MAIN_PROPULSION_CAN::currentVoltageThresholds{0, 800, 750};

二、成员函数实现语法

类成员函数的实现需要包含类名限定符,如代码中展示的阈值设置函数:

void MAIN_PROPULSION_CAN::setVoltageThresholds(const VoltageThresholds& thresholds) {currentVoltageThresholds = thresholds;
}

语法要点:

  1. 返回类型:void表示函数不返回值
  2. 函数名前的类限定:MAIN_PROPULSION_CAN::表明这是类的成员函数
  3. 参数:const VoltageThresholds& thresholds - 常量引用参数,避免拷贝开销
  4. 函数体:简单的赋值操作,将参数值赋给静态成员变量

三、const引用参数的重要性

所有setter函数都使用了const引用参数:

void MAIN_PROPULSION_CAN::setTemperatureThresholds(const TemperatureThresholds& thresholds)

这样设计的好处:

  1. 避免大对象拷贝带来的性能开销
  2. const保证函数内不会意外修改传入的参数
  3. 引用传递比指针更安全,语法更简洁

四、静态成员变量的访问

在成员函数内部,静态成员变量可以直接访问:

currentTemperatureThresholds = thresholds;

虽然静态成员属于类而非对象,但在类的成员函数中访问时不需要类名限定。

五、良好的封装实践

这段代码展示了良好的面向对象封装原则:

  1. 数据成员设为private,防止外部直接修改
  2. 通过public的setter函数控制对内部状态的修改
  3. 相关阈值以结构体形式组织,提高代码可读性
  4. 静态成员集中管理全局配置

六、实际应用建议

在实际工程中,这种模式可以扩展为:

  1. 添加参数有效性检查
  2. 增加线程安全保护(如mutex)
  3. 添加日志记录阈值变更
  4. 实现观察者模式通知相关组件阈值变化

这种结构体加成员函数的模式在硬件接口、配置管理等场景非常实用,既能保持代码组织清晰,又能提供灵活的参数调整能力。


拓展:

深入了解一下 const TimingThresholds& thresholds 的用法。

1. 语法解析

  • const:表示这个引用指向的对象是常量,不能通过这个引用修改对象的内容。
  • TimingThresholds:这是一个结构体类型,表示一组时间相关的阈值。
  • &:表示这是一个引用,而不是一个副本。引用是一个别名,它指向实际的对象,而不是创建一个新的对象。
  • thresholds:这是引用的变量名,表示通过这个引用可以访问实际的 TimingThresholds 对象。

2. 为什么使用引用

在C++中,引用(&)是一种非常有用的技术,它允许函数直接操作传入的参数,而不是操作参数的副本。这有以下几个优点:

  • 性能优化:如果传递的对象比较大(例如一个大的结构体或类),传递引用可以避免复制整个对象,从而节省时间和内存。
  • 直接修改:如果需要在函数内部修改传入的对象,使用引用可以直接修改原始对象,而不是修改一个副本。

3. 为什么使用 const 引用

使用 const 引用可以确保函数不会修改传入的对象。这有以下几个优点:

  • 安全性:可以防止函数意外地修改传入的对象,从而避免潜在的错误。
  • 兼容性:允许函数接受常量对象作为参数,而不仅仅是非常量对象。这使得函数更加通用,可以接受更广泛的参数类型。

4. 示例代码

假设我们有一个 TimingThresholds 结构体,定义如下:

struct TimingThresholds {int64_t outputTooFastThreshold;int64_t outputTooSlowThreshold;int64_t noOutputThreshold;int64_t feedbackTooFastThreshold;int64_t feedbackTooSlowThreshold;int64_t feedbackTimeoutThreshold;
};

现在,我们定义一个函数,它接受一个 const TimingThresholds& 参数:

void printThresholds(const TimingThresholds& thresholds) {std::cout << "Output too fast threshold: " << thresholds.outputTooFastThreshold << " ns" << std::endl;std::cout << "Output too slow threshold: " << thresholds.outputTooSlowThreshold << " ns" << std::endl;std::cout << "No output threshold: " << thresholds.noOutputThreshold << " ns" << std::endl;std::cout << "Feedback too fast threshold: " << thresholds.feedbackTooFastThreshold << " ns" << std::endl;std::cout << "Feedback too slow threshold: " << thresholds.feedbackTooSlowThreshold << " ns" << std::endl;std::cout << "Feedback timeout threshold: " << thresholds.feedbackTimeoutThreshold << " ns" << std::endl;
}

在这个函数中,thresholds 是一个对传入的 TimingThresholds 对象的引用,但它是一个 const 引用,因此我们不能通过 thresholds 修改原始对象。

5. 调用函数

现在,我们创建一个 TimingThresholds 对象,并将其传递给 printThresholds 函数:

int main() {TimingThresholds thresholds = {200000, 80000, 120000, 400, 500, 5000};printThresholds(thresholds);return 0;
}

在这个例子中,thresholds 是一个 TimingThresholds 对象,我们将其传递给 printThresholds 函数。由于 printThresholds 函数接受一个 const TimingThresholds& 参数,因此它不会修改 thresholds 对象,同时避免了复制整个对象的开销。

6. 总结

  • const TimingThresholds& thresholds 表示函数接受一个对 TimingThresholds 对象的常量引用。
  • 使用引用可以避免复制对象,提高性能。
  • 使用 const 引用可以确保函数不会修改传入的对象,提高代码的安全性和兼容性。
  • 这种用法在处理大型对象或需要保证函数不会修改参数时非常有用。

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

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

相关文章

买了新内存条插上bios识别,进入系统不可用,b450主板,内存插槽A1A2 可以点亮,B1B2不可以,A2B2不可以,B1B2还是不可以

提示&#xff1a;买了新内存条插上bios识别&#xff0c;进入系统不可用&#xff0c;b450主板&#xff0c;内存插槽A1A2 可以点亮&#xff0c;B1B2不可以&#xff0c;A2B2不可以 文章目录 前言——环境一、第一种情况&#xff0c;开机不能点亮二、第二种情况, 总内存&#xff0c…

7.4.1_2B树的插入删除

B树插入&#xff1a; 假如是m阶B树&#xff0c;插入关键字时都要满足每个节点上的关键字个数最少为m/2向上取整-1关键字&#xff0c;最多有m-1个关键字&#xff0c;且每次插入的新元素一定是放在最底层的终端节点(因为如果不是放在终端节点&#xff0c;会导致该节点上可能有叶子…

Linux系统基本操作指令

Linux系统基本操作指令 文章目录 Linux系统基本操作指令一、介绍二、基础设置2.1 设置ubuntu与window的共享目录2.2 ubuntu系统简单介绍 三、Linux命令及工具介绍3.1 目录管理命令(功能&#xff0c;格式&#xff0c;参数&#xff0c;系统参数)3.2 文件操作命令 四、网络命令4.1…

系统思考VS心智模式

在这张图片中&#xff0c;我们看到的是两杯相同价格的咖啡&#xff0c;它们的价格显示方式不同。一杯咖啡的原价和现价都写得很大&#xff0c;而另一杯的价格则以较小的字体呈现。这种微妙的设计差异揭示了一个有趣的心理现象——心智模式。 人们在面对同样的价格时&#xff0…

all()函数和any()函数

参考文献 在if上使用.all和.any # 中心点未改变&#xff0c;说明达到稳态&#xff0c;结束递归if (self.points new_center).all():sum self.__sumdis(result)return result, self.points, sum

Maven:依赖管理就像乐高拼装的艺术

目录 &#x1f3d7;️ 第一章&#xff1a;Maven是高级乐高玩家&#x1f50d; 依赖管理的基本单元 &#x1f9e9; 第二章&#xff1a;多模块项目——乐高巨舰组装术&#x1f31f; 为什么要拆分模块&#xff1f;&#x1f6e0;️ 父子POM配置示范 ⚔️ 第三章&#xff1a;依赖冲突…

空间数据挖掘 期末复习

前言&#xff1a;此篇复习笔记结合了课程ppt和deepseek回答进行总结&#xff0c;如有谬误恳请指正。 期末考例题 &#xff08;名词解释*10、简答*6、论述*6&#xff09; 一、名词解释 数据挖掘 过拟合&#xff08;Overfitting&#xff09; Apriori算法 决策树&#xff08;…

跳跳杆、弹跳杆、Poto stick:百年弹跳玩具的健康与使用分享(大模型改写)

跳跳杆&#xff1a;百年弹跳神器的健康争议与安全指南 &#xff08;用DeepSeek改写前一篇文章&#xff0c;可惜没有接广告&#xff0c;否则植入一些链接多好&#xff09; &#x1f50d; 一、健康功效&#xff1a;惊喜与风险并存 争议性健康主张 坊间流传跳跳杆可能具备&…

WHAT - React Native 开发 App 从 0 到上线全流程周期

文章目录 一、React Native App 开发流程总览二、各阶段详细说明需求分析 & 产品规划技术选型 & 方案确定项目初始化A. 使用 Expo&#xff08;推荐新手&#xff09;B. 使用 React Native CLI&#xff08;自由度更高&#xff09; UI 开发 功能开发&#xff08;主开发阶…

Windows11 无法发现局域网内设备解决方法

临时解决 发生问题绝大多数Windows11 24H2版本&#xff0c;该版本目前来看没有永久解决方案 初步问题可以定位在FDResPub服务问题&#xff0c;重启该服务可以短暂恢复&#xff0c;临时解决方案就是重启该服务&#xff0c;然后把网络设备右键创建快捷方式 做成批处理文件 创建…

张 心理健康咨询相关论文;AI心理咨询数字孪生:个性化风格的突破

张 心理健康咨询相关论文 EmoLLM:多模态情感理解与大型语言模型的结合 PsyDT:使用 LLM 构建具有个性化咨询风格的心理咨询师数字孪生 目前,大型语言模型 (LLM) 在心理咨询领域取得了重大进展。然而,现有的心理健康 LLM 忽略了一个关键问题,即他们没有考虑不同的心理咨…

通达信【千军趋势决策系统】幅图指标

指标功能说明 本指标基于价格波动与趋势转折点,结合K线形态分析,提供多维度买卖信号,适用于股票、期货等趋势交易场景。 核心信号解读 「横扫千军」 触发条件:短期、中期、长期趋势同时确认反转向上。 用法:趋势共振信号,提示较强多头机会,可结合成交量验证。 「出击!…

大模型LoRA微调实践

大模型LoRA微调实践 准备工作 数据集&#xff1a;采用 GitHub 上的 Chinese-medical-dialogue-data 中文医疗对话数据集 Github地址如下&#xff1a; https://github.com/Toyhom/Chinese-medical-dialogue-data 微调模型&#xff1a; Qwen 1.5B模型&#xff08;Qwen2、2.5均…

跟着AI学习C#之项目实践Day1

&#x1f9ed; 实战项目&#xff1a;博客平台系统 - Day1 &#x1f3d7;️ 目标 创建新的 ASP.NET Core 项目添加 EF Core 和 Identity 支持实现用户注册、登录功能运行并测试基本身份验证流程 &#x1f5d2;️ 任务清单 1. 创建新项目 打开 Visual Studio 或 Visual Studi…

Java面试复习指南:基础、面向对象、Java 8新特性及并发编程

Java面试复习指南&#xff1a;基础、面向对象、Java 8新特性、常用框架及并发编程 面试中&#xff0c;Java开发者常被问及多个核心技术点。本文从以下几个方面帮助考生快速复习&#xff1a; Java基础 概念解析&#xff1a;Java是一种面向对象的高级编程语言&#xff0c;具有…

微信小程序form表单手机号正则检验pattern失效

好奇怪啊&#xff0c;h5页面校验没问题&#xff0c;在微信小程序模拟器以及真机运行都失效&#xff0c;排查半天&#xff0c;记录一下 PS&#xff1a;身份证号校验也没问题&#xff0c;就手机号校验有问题&#xff0c;奇奇怪怪的 之前的写法&#xff08;在小程序上不生效&…

基于LQR的双积分小车轨迹跟踪控制系列(三)从连续到离散:双积分小车状态空间的数字实现

为什么要离散化&#xff1f; 以便在数字硬件和仿真程序中使用。 离散化的数学推导 连续状态空间&#xff1a; 双积分小车的简化形式 由于双积分小车的 A 矩阵结构简单&#xff08;A0&#xff09;&#xff0c;矩阵指数可以化简&#xff1a; Python实现&#xff08;示例代码&am…

如何在服务器终端下载百度网盘数据

使用BaiduPCS-Go在终端实现远程服务器对百度网盘数据的上传与下载流程学习 BaiduPCS-Go可用于访问和管理百度网盘文件资源的命令行客户端下载百度网盘数据至服务器从服务器中上传文件至百度网盘中BaiduPCS-Go可用于访问和管理百度网盘文件资源的命令行客户端 下载百度网盘数据…

消息队列:基本知识

定义 队列 Queue 是一种先进先出的数据结构&#xff0c;所以消费消息时也是按照顺序来消费的 消息队列看作是一个存放消息的容器&#xff0c;需要使用消息的时候&#xff0c;直接从容器中取出消息供自己使用即可 参与消息传递的双方称为 生产者 和 消费者 生产者负责发送消…

算法-动态规划-钢条切割问题

钢条切割问题是一个经典的动态规划问题&#xff0c;旨在通过切割钢条获得最大收益。以下是详细解释和解决方案&#xff1a; 问题描述 给定长度为 n 的钢条和价格表 p&#xff0c;其中 p[i] 表示长度为 i 的钢条的价格&#xff08;i 1, 2, ..., n&#xff09;。目标&#xff…