More Effective C++ 35个改善编程与设计的有效方法笔记与心得 2

二. 操作符

条款5: 对定制的“类型转换参数”保持警觉

‌‌‌‌  在编程中,类型转换是将一种数据类型变为另一种数据类型。这个过程在很多情况下都是非常有用的,比如从浮点数向整数转换,或者从基类向派生类转换。然而,如果不正确使用,可能会产生非预期的副作用,例如数据丢失,或者转换失败

‌‌‌‌  当你看到"对定制的类型转换参数保持警觉"的建议时,这通常是指在设计和使用自定义的类型转换函数时需要特别小心。类型转换运算符是C++允许你定义的一种特殊成员函数,可将一个类类型的值转换为另一种类型。它们在使用上非常方便,但是如果在设计和使用上没有控制得当,就可能带来很多问题。

‌‌‌‌  例如,自定义的类型转换函数可能在没有明确要求的情况下被隐式调用,可能导致意外的转换和潜在的错误。另一个问题是,如果类型转换函数不清楚,阅读和维护代码的人可能无法理解代码的目的和效果,这可能会导致错误

‌‌‌‌  所以,"对定制的类型转换参数保持警觉"这个建议的含义是:在设计和使用类型转换函数时,应该注意明确、谨慎并尽量避免使用隐式类型转换,以减少潜在的错误

条款6: 区别 increment/decrement 操作符的前置(prefix)和后置(profix)形式

‌‌‌‌  在C++和其他一些编程语言中,我们经常会遇到增量(increment)和减量(decrement)这两类操作符,它们分别被记作 ++ 和 --。当它们作用在一个变量上时,可以用来增加或减少变量的值。

‌‌‌‌  这两个操作符有两种使用形式:前置(prefix)形式和后置(postfix)形式。

1. 前置(prefix)形式

‌‌‌‌  前置形式先进行计算,然后再进行赋值。例如,++i--i。这种形式先改变i的值,然后再进行其他的计算。比如在表达式int a = ++i;中,先把i增加1,然后再把新值赋给a。
‌‌‌‌

2. 后置(postfix)形式

‌‌‌‌  后置形式先进行赋值,然后再进行计算,例如,i++i--。在一个表达式中使用后置增量或减量操作符,会先进行其他的计算,然后再改变i的值。比如在表达式int a = i++;中,首先把i的当前值赋给a,再把i加1。

‌‌‌‌  所以"区别 increment/decrement 操作符的前置(prefix)和后置(postfix)形式"的意思就是让我们理解和区分这两种操作符形式的不同。在实践中,我们往往需要根据具体的需求和场景来选择使用哪种形式。

条款7: 千万不要重载&& , || 和 , 操作符

请记住:
‌‌‌‌  在C++编程中,重载操作符是允许的,允许你为自定义类型(例如类和结构体)定义自己的行为。不过,并不是所有操作符都适合被重载,特别是像&&||,(逗号)这些操作符。

&&|| 操作符

  1. 短路求值(Short-circuit Evaluation):

    • 逻辑与(&&)逻辑或(||) 操作符在C++中具有短路求值的特性。如果第一个操作数能够确定整个表达式的值,第二个操作数就不会被求值。例如:

      if (a && b) { /* ... */ }

      如果 afalse,则 b 不会被求值。这种特性在逻辑判断中非常重要,有助于避免不必要的计算,甚至可以防止潜在的运行时错误(例如 b 可能是一个需要非空检查的指针)。

  2. 重载后可能失去短路求值的特性:

    • 如果重载了这些操作符,编译器将无法再使用这种短路特性,因为重载的版本会被认为是普通函数调用,所有参数都会被求值。这不仅会影响程序的性能,还可能引入潜在的bug和不可预见的行为。

, 操作符

  1. 顺序求值(Sequencing):

    • 逗号操作符在C++中的作用是顺序求值,其表达式中左侧的操作数先被求值,然后右侧的操作数被求值,整个表达式的结果是右侧操作数的结果。例如:

      int x = (a++, b++);

      在这个例子中,a 被先增加然后是 bx 最终被赋值为 b++ 的结果。

  2. 重载后的复杂性和不明确性:

    • 重载逗号操作符会使代码变得难以理解和维护。通常,开发者不会期望逗号操作符有不同的行为,而这种不一致性可能导致程序的逻辑难以跟踪和调试。

总结

‌‌‌‌  重载这些操作符会带来很多潜在的问题,使代码的行为不再符合直觉,并且可能引入性能问题和bug。因此,建议避免重载这些操作符,以保持代码的可读性和可靠性。

条款8: 了解各种不同意义的new和delete

‌‌‌‌  在C++中,newdelete 操作符有多种不同的用途和意义。了解这些不同的用法有助于更好地管理内存,并编写高效、健壮的代码。以下是对各种不同意义的 newdelete 的解释:

new 操作符

  1. 常规动态内存分配:

    • 用于从堆中分配单个对象的内存。

    int* p = new int; // 分配一个 int 类型的对象 *p = 5;

    • 用于从堆中分配数组的内存。

    int* pArray = new int[10]; // 分配一个 int 类型的数组,包含 10 个元素

  2. 带参数的构造函数:

    • 可以使用 new 操作符调用带参数的构造函数。

    class MyClass { public: MyClass(int x) : value(x) {} private: int value; }; MyClass* obj = new MyClass(10); // 使用带参数的构造函数创建对象

  3. 定位 new (placement new):

    • 定位 new 允许在预先分配的内存上构造对象。常用于自定义内存管理。

    char buffer[sizeof(MyClass)]; MyClass* p = new(buffer) MyClass(10); // 在 buffer 上构造 MyClass 对象

    • 使用定位 new 时,需要包含头文件 <new>

delete 操作符

  1. 常规动态内存释放:

    • 用于释放使用 new 分配的单个对象的内存。

    delete p; // 释放单个对象的内存

    • 用于释放使用 new 分配的数组的内存。

    delete[] pArray; // 释放数组的内存

  2. 定位 delete (placement delete):

    • 对于定位 new 构造的对象,应该显式调用析构函数,因为定位 new 不分配内存,只是在指定位置上构造对象。

    p->~MyClass(); // 显式调用析构函数

    • 定位 delete 并不真正释放内存,因为内存的分配和释放是由程序员自己管理的。

特殊情况和运用

  1. 自定义 new 和 delete:

    • 类可以重载全局的 newdelete 操作符,以实现自定义的内存管理策略。

    void* operator new(size_t size) { // 自定义内存分配逻辑 } void operator delete(void* p) { // 自定义内存释放逻辑 }

    • 可以在类内重载,也可以在全局范围重载。
  2. 避免内存泄漏和野指针:

    • 在使用 newdelete 时,必须确保每个 new 都有对应的 delete,否则会导致内存泄漏。
    • 释放指针后,建议将其设置为 nullptr,避免成为悬挂指针(dangling pointer)。

    delete p; p = nullptr;

总结

‌‌‌‌  了解和正确使用 newdelete 及其各种不同的形式和用法,对于C++程序员来说是非常重要的。这不仅有助于有效管理内存资源,还能提高程序的健壮性和性能。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM相关总结

JVM的些许问题 1.JVM内存区域划分 2.JVM类加载过程 3.JVM的垃圾回收机制 1.JVM的内存区域划分 一个运行起来的Java进程就是一个JVM虚拟机,需要从操作系统申请一大片内存,就会把内存划分成几个区域,每个区域都有不同的作用 常见的面试题 2.JVM类加载过程 熟练背诵 ! ! !…

Winform使用Flurl调用WebApi的基本用法

微信公众号“CSharp编程大全"的文章《.NET超简单轻量级的HTTP请求组件Flurl》介绍了便捷构建URL及创建HTTP请求的.NET模块Flurl。与HttpClient相比,Flurl封装的更简捷易用&#xff0c;代码量更少。本文学习并测试基于Fluri调用WebApi的基本用法。   基于Fluri调用WebApi…

怎么找python的运行路径

1.命令行中执行&#xff1a; import sys print(sys.argv[0]) 执行后为空。 2. import os os.path.abspath(os.curdir) 3. import os os.getcwd()

LeetCode-213. 打家劫舍 II【数组 动态规划】

LeetCode-213. 打家劫舍 II【数组 动态规划】 题目描述&#xff1a;解题思路一&#xff1a;分三种情况&#xff0c;一&#xff1a;不考虑头尾&#xff1b;二&#xff1a;考虑头不考虑尾&#xff1b;三&#xff1a;考虑尾不考虑头。解题思路二&#xff1a;优化空间解题思路三&am…

如何利用python画出AHP-SWOT的战略四边形(四象限图)

在企业或产业发展的相关论文分析中&#xff0c;常用到AHP-SWOT法进行定量分析&#xff0c;形成判断矩阵后&#xff0c;如何构造整洁的战略四边形是分析的最后一个环节&#xff0c;本文现将相关代码发布如下&#xff1a; import mpl_toolkits.axisartist as axisartist import …

java之命令执行审计思路

1 漏洞原理 因用户输入未过滤或净化不完全&#xff0c;导致Web应用程序接收用户输入&#xff0c;拼接到要执行的系统命令中执行。一旦攻击者可以在目标服务器中执行任意系统命令&#xff0c;就意味着服务器已被非法控制。 2 审计中常用函数 一旦攻击者可以在目标服务器中执行…

【AIGC】AnimateAnyone:AI赋予静态照片生命力的魔法

摘要&#xff1a; 在人工智能技术的不断进步中&#xff0c;AnimateAnyone项目以其创新性和易用性脱颖而出&#xff0c;成为GitHub上备受瞩目的AI项目之一。由阿里巴巴智能计算研究院开发的这一技术&#xff0c;允许用户通过提供一张静态照片&#xff0c;快速生成动态角色。本文…

SpringBoot(一)创建一个简单的SpringBoot工程

Spring框架常用注解简单介绍 SpringMVC常用注解简单介绍 SpringBoot&#xff08;一&#xff09;创建一个简单的SpringBoot工程 SpringBoot&#xff08;二&#xff09;SpringBoot多环境配置 SpringBoot&#xff08;三&#xff09;SpringBoot整合MyBatis SpringBoot&#xff08;四…

docker安装rocketMq5x以上的版本

1.背景 安装RocketMQ 5.x以上的版本主要是因为新版本引入了许多性能优化、新功能以及对已有特性的增强&#xff0c;这些改进可以帮助提升消息队列系统的稳定性和效率。 1.性能提升&#xff1a;RocketMQ 5.x版本通常包括了对消息处理速度、吞吐量和延迟的优化&#xff0c;使得系…

在Linux (Ubuntu 16) 下安装LabVIEW

用户尝试在Ubuntu 16操作系统上安装LabVIEW&#xff0c;但找不到合适的安装文件来支持Ubuntu。已经下载了运行时文件&#xff0c;并尝试将.rpm包转换为.deb包并安装在Ubuntu上。然而&#xff0c;安装完成后&#xff0c;没有在应用程序中看到LabVIEW的图标。 用户希望能够在Ubu…

Spring MVC中的DispatcherServlet、HandlerMapping和ViewResolver的作用

在Spring MVC框架中&#xff0c;DispatcherServlet、HandlerMapping和ViewResolver是核心组件&#xff0c;它们各自承担着不同的角色和任务&#xff1a; 1.DispatcherServlet&#xff1a;它是Spring MVC生命周期中的前端控制器&#xff0c;负责接收HTTP请求并将它们分发给相应的…

【OpenREALM学习笔记:13】pose_estimation.cpp和pose_estimation.h

UML Class Diagram 图中红色框为头文件中所涉及到的函数、变量和结构体 核心函数 PoseEstimation::process() 其核心作用为执行位姿估计的处理流程&#xff0c;并返回是否在此循环中进行了任何处理。 在这个函数中判断并完成地理坐标的初始化或这地理坐标的更新。 这里需要…

论文阅读_基本于文本嵌入的信息提取

英文名&#xff1a;Embedding-based Retrieval with LLM for Effective Agriculture Information Extracting from Unstructured Data 中文名&#xff1a;基于嵌入的检索&#xff0c;LLM 从非结构化数据中提取有效的农业信息 地址: https://arxiv.org/abs/2308.03107 时间&…

昇思25天学习打卡营第04天|数据集 Dataset

数据是深度学习的基础&#xff0c;高质量的数据输入将在整个深度神经网络中起到积极作用。MindSpore提供基于Pipeline的数据引擎&#xff0c;通过数据集&#xff08;Dataset&#xff09;和数据变换&#xff08;Transforms&#xff09;实现高效的数据预处理。其中Dataset是Pipel…

【linux】网络基础(1)

文章目录 网络基本概念网络的定义网络的类型局域网&#xff08;LAN&#xff09;广域网&#xff08;WAN&#xff09; 网络协议OSI七层模型TCP/IP模型TCP/IP模型的结构 网络传输的基本流程计算机与计算机之间的通信计算机的信息处理封装报头 网络基本概念 网络的定义 1.网络是指…

1.搭建篇——帝可得后台管理系统

目录 前言项目搭建一、搭建后端项目1.初始化项目Maven构建 2.MySQL相关导入sql配置信息 3. Redis相关启动配置信息 4.项目运行 二、 搭建前端项目1.初始化项目2.安装依赖3.项目运行 三、问题 前言 提示&#xff1a;本篇讲解 帝可得后台管理系统 项目搭建 项目搭建 一、搭建后…

【2024-热-办公软件】ONLYOFFICE8.1版本桌面编辑器测评

在今日快速发展的数字化办公环境中&#xff0c;选择一个功能全面且高效的办公软件是至关重要的。最近&#xff0c;我有幸体验了ONLYOFFICE 8.1版本的桌面编辑器&#xff0c;这款软件不仅提供了强大的编辑功能&#xff0c;还拥有众多改进&#xff0c;让办公更加流畅和高效。在本…

DCS-11双位置继电器 DC220V 板前接线带底座 约瑟 JOSEF

系列型号&#xff1a; DCS-11双位置继电器&#xff1b; DCS-12双位置继电器&#xff1b; DCS-13双位置继电器&#xff1b; ​用途 RXMVB2(DCS-10)系列双位置继电器用于需要大容量双稳态触点的工业控制和其它一般控制场合。 特点 体积小&#xff0c;拆装方便&#xff0c;能安…

Halcon 椭圆

一 椭圆 方差的概念: 例1 两人的5次测验成绩如下&#xff1a;X&#xff1a; 50&#xff0c;100&#xff0c;100&#xff0c;60&#xff0c;50 E(X)72&#xff1b;Y&#xff1a; 73&#xff0c; 70&#xff0c; 75&#xff0c;72&#xff0c;70 E(Y)72。平均成绩相同&#xff0c…

[Cloud Networking] OSPF

OSPF 开放式最短路径优先&#xff08;Open Shortest Path First&#xff09;是一种动态路由协议&#xff0c;它属于链路状态路由协议&#xff0c;具有路由变化收敛速度快、无路由环路、支持变长子网掩码和汇总、层次区域划分等优点。 1 OSPF Area 为了适应大型网络&#xff0…