More effective C++:杂项

Item M32:在未来时态下开发程序

(1)适应变化:软件开发人员应认识到软件需求和技术环境会随时间变化,因此在设计和编码时应具备前瞻性,使软件能够适应未来的需求和平台变化。

(2)预防性设计:在设计类和接口时,应该考虑未来可能出现的功能扩展和代码重用。例如,如果一个类有可能被继承,则应提前声明虚析构函数,即便当前没有派生类。

(3)使用语言特性强制设计约束:利用C++的语言特性来实现设计意图,比如通过将某些成员函数声明为私有来防止不希望的操作,或者使用模板和泛型编程来提高代码的灵活性和复用性。

(4)易于理解和维护:编写清晰、易于理解的代码,考虑到未来的维护者可能不是原始开发者。这包括提供良好的文档、遵循良好的编程实践等。

(5)健壮性和错误处理:预见用户可能会犯的错误,并设计代码以防止、检测或修复这些错误。这有助于提高软件的健壮性和用户体验。

(6)可移植性:尽可能编写可移植的代码,除非性能是绝对关键的因素。可移植的代码更容易适应不同的平台和环境,也有助于扩大用户基础。

(7)局部化变化的影响:设计时应尽量减小更改一处代码对其他部分的影响,通过封装和模块化等方式实现。

(8)考虑长期生存能力:虽然软件需要满足当前的需求,但是过度关注眼前可能会牺牲软件的长期生存能力和价值。优秀的软件不仅能满足当前的需求,还能在未来的变化中保持相关性和竞争力。

Item M33:将非尾端类设计为抽象类

非尾端类(Non-Leaf Class)指那些被设计为基类,且预期会有派生类的类。这些类通常包含一些通用的行为和属性,但它们本身可能不适合直接实例化。它们的设计目的是为了让派生类继承并扩展其功能。在继承层次中,如果基类 Animal 有赋值操作符 operator=,而派生类 Lizard 和 Chicken 也有各自的赋值操作符,通过基类指针进行赋值时,只会调用基类的赋值操作符,导致部分赋值问题

首先,我们来看一下作者给出的初始代码示例,以及如何通过引入抽象类来解决问题。

class Animal {
public:Animal& operator=(const Animal& rhs);// 其他成员...
};
class Lizard : public Animal {
public:Lizard& operator=(const Lizard& rhs);// 其他成员...
};
class Chicken : public Animal {
public:Chicken& operator=(const Chicken& rhs);// 其他成员...
};
Lizard liz1;
Lizard liz2;
Animal *pAnimal1 = &liz1;
Animal *pAnimal2 = &liz2;
*pAnimal1 = *pAnimal2;  // 只赋值了 Animal 部分,Lizard 部分未被赋值

解决方案:引入抽象类

class AbstractAnimal {
protected:AbstractAnimal& operator=(const AbstractAnimal& rhs);
public:virtual ~AbstractAnimal() = 0;  // 纯虚析构函数// 其他成员...
};
// 纯虚析构函数的实现
AbstractAnimal::~AbstractAnimal() {}
class Animal : public AbstractAnimal {
public:Animal& operator=(const Animal& rhs);// 其他成员...
};
class Lizard : public AbstractAnimal {
public:Lizard& operator=(const Lizard& rhs);// 其他成员...
};
class Chicken : public AbstractAnimal {
public:Chicken& operator=(const Chicken& rhs);// 其他成员...
};

解决方案:

通过引入一个抽象基类 AbstractAnimal,将 Animal、Lizard 和 Chicken 都从 AbstractAnimal 继承。

纯虚析构函数:在 AbstractAnimal 中声明一个纯虚析构函数 virtual ~AbstractAnimal() = 0;,并在类外实现它。这使得 AbstractAnimal 成为一个抽象类,不能被实例化。

保护赋值操作符:将 AbstractAnimal 的赋值操作符声明为 protected,以防止通过基类指针进行赋值。

优点:

通过抽象类和保护赋值操作符,避免了通过基类指针进行部分赋值的问题。

确保赋值操作的正确性,避免运行时错误。如果未来需要添加新的动物类,只需从 AbstractAnimal 继承即可,不会影响现有代码。

缺点:

增加复杂度:引入抽象类会增加代码的复杂度,需要额外的类和成员函数。

编译开销:需要重新编译涉及 Animal、Lizard 和 Chicken 的代码。

设计原则:

非尾端类应该是抽象类:如果一个类被设计为基类,且有派生类,那么它应该是抽象类。这有助于确保派生类的行为正确性,避免部分赋值等问题。

明确抽象行为:通过引入抽象类,强迫设计者明确识别和定义有用的抽象行为,提高代码的可读性和可维护性。

Item M34:如何在同一程序中混合使用 C++和 C

1. 确保编译器兼容性

在混合使用 C++ 和 C 时,首先需要确保 C++ 编译器和 C 编译器生成的 .obj 文件是兼容的。因为不同的编译器在实现相关的特性(如 int 和 double 的字节大小、传参方式等)上可能有所不同。

2. 名变换

名变换:C++ 编译器会给函数名进行变换,以支持函数重载。C 语言中没有函数重载,因此不需要名变换。如果 C++ 代码调用 C 函数,C++ 编译器会对函数名进行变换,而 C 代码中函数名保持不变,导致链接错误。

解决方法:使用 extern "C" 声明 C 函数,禁止名变换。

extern "C" void drawLine(int x1, int y1, int x2, int y2);

批量声明:可以使用 extern "C" 包裹一组函数,以简化代码。

extern "C" {void drawLine(int x1, int y1, int x2, int y2);void twiddleBits(unsigned char bits);void simulate(int iterations);
}

条件编译:使用 #ifdef __cplusplus 宏来确保在 C++ 编译时添加 extern "C",而在 C 编译时不添加。

#ifdef __cplusplus
extern "C" {
#endif
void drawLine(int x1, int y1, int x2, int y2);
void twiddleBits(unsigned char bits);
void simulate(int iterations);
#ifdef __cplusplus
}
#endif

3. 静态初始化

静态初始化:C++ 在 main 执行前会自动调用静态对象的构造函数,执行静态初始化。同样,在 main 结束后会调用静态对象的析构函数。

如果 main 是用 C 编写的,静态对象的构造和析构可能不会被正确调用。

解决方法:用 C++ 写 main 函数,即使程序的大部分是用 C 编写的。可以通过将 C 的 main 改名为 realMain,然后在 C++ 的 main 中调用 realMain。

extern "C" int realMain(int argc, char *argv[]);
int main(int argc, char *argv[]) {return realMain(argc, argv);
}

4. 动态内存分配

规则:C++ 部分使用 new 和 delete,C 部分使用 malloc 和 free。

用 free 释放 new 分配的内存或用 delete 释放 malloc 分配的内存,其行为未定义。

解决方法:严格隔离 new 和 delete 与 malloc 和 free 的使用。

char *strdup(const char *ps); // C 函数库中的函数
char *str = strdup("Hello, World");
free(str); // 用 free 释放 C 函数库分配的内存

尽量避免调用那些既不在标准库中也没有固定形式的函数,以减少可移植性问题。

5. 数据结构的兼容性

C 函数不了解 C++ 的特性,因此在 C++ 和 C 之间传递数据时,只能使用 C 可表示的概念。:可以安全传递普通指针、指向非成员函数或静态成员函数的指针、结构和内建类型(如 int、char 等)。

结构兼容性:C++ 中的 struct 规则兼容 C 中的规则,因此相同的结构可以在 C++ 和 C 之间安全传递。增加非虚成员函数不会影响兼容性,但增加虚函数或进行继承会影响内存结构,从而影响兼容性。

struct Point {int x;int y;
};
// C++ 版本
struct PointWithMethods {int x;int y;void move(int dx, int dy) {x += dx;y += dy;}
};
// C 版本
struct PointWithMethods {int x;int y;
};

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

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

相关文章

【从零开始的LeetCode-算法】3270. 求出数字答案

给你三个 正 整数 num1 &#xff0c;num2 和 num3 。 数字 num1 &#xff0c;num2 和 num3 的数字答案 key 是一个四位数&#xff0c;定义如下&#xff1a; 一开始&#xff0c;如果有数字 少于 四位数&#xff0c;给它补 前导 0 。答案 key 的第 i 个数位&#xff08;1 < …

STM32+AI语音识别智能家居系统

基于 STM32 和 AI 语音识别的智能家居系统的详细硬件和软件设计&#xff0c;包括各个模块的详细描述和代码示例。 一、硬件设计 1. 微控制器&#xff08;STM32&#xff09;&#xff1a; 选择 STM32F7 系列或更高性能的芯片&#xff0c;如 STM32F767ZIT6&#xff0c;以满足处理…

信息收集—JS框架识别泄露提取API接口泄露FUZZ爬虫插件项目

前言 免杀结束了&#xff0c;我们开个新的篇章——信息收集。为什么我一开始先写信息收集的文章呢&#xff0c;是因为现在我才发现我的信息收集能力其实有点弱的&#xff0c;所以呢开始知不足&#xff0c;而后进。 什么是JS JS就是JavaScript的简称&#xff0c;它和Java是没…

智能化护士排班系统的设计与实现(文末附源码)

自动排班-护士(分白班|夜班) 当服务器启动时检测需要自动排班,自动开始排班的算法执行 获得本周的所有日期,例如2023-01-29.....2023-02-04依次对每个科室&#xff0c;从第一天开始,逐天进行排班&#xff0c;分别设置两个二个数组&#xff0c;day[7];night[7]分别记忆一周内每…

【原创】java+ssm+mysql社区疫情防控管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

Flink Source 详解

Flink Source 详解 原文 flip-27 FLIP-27 介绍了新版本Source 接口定义及架构 相比于SourceFunction&#xff0c;新版本的Source更具灵活性&#xff0c;原因是将“splits数据获取”与真“正数据获取”逻辑进行了分离 重要部件 Source 作为工厂类&#xff0c;会创建以下两…

CSS回顾-基础知识详解

一、引言 在前端开发领域&#xff0c;CSS 曾是构建网页视觉效果的关键&#xff0c;与 HTML、JavaScript 一起打造精彩的网络世界。但随着组件库的大量涌现&#xff0c;我们亲手书写 CSS 样式的情况越来越少&#xff0c;CSS 基础知识也逐渐被我们遗忘。 现在&#xff0c;这种遗…

11.08-10.14谷粒商城

谷粒商城--品牌管理 前端表单校验 品牌新增 品牌修改 校验规则 dataRule: {name: [{ required: true, message: "品牌名不能为空", trigger: "blur" }],logo: [{ required: true, message: "品牌logo地址不能为空", trigger: "blur"…

无插件H5播放器EasyPlayer.js网页web无插件播放器选择全屏时,视频区域并没有全屏问题的解决方案

EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、HTTP-FLV、HLS&#xff08;m3u8&#xff09;、WS、WEBRTC、FMP4视频直播与视频点播等多种协议&#xff0c;支持H.264、H.265、AAC、G711A、MP3等多种音视频编码格式&#xff0c;支持MSE、WASM、WebCodec等多种解码方…

基于Spring Boot的电子商务系统设计

5 系统实现 系统实现部分就是将系统分析&#xff0c;系统设计部分的内容通过编码进行功能实现&#xff0c;以一个实际应用系统的形式展示系统分析与系统设计的结果。前面提到的系统分析&#xff0c;系统设计最主要还是进行功能&#xff0c;系统操作逻辑的设计&#xff0c;也包括…

CSP-X2024山东小学组T2:消灭怪兽

题目链接 题目名称 题目描述 怪兽入侵了地球&#xff01; 为了抵抗入侵&#xff0c;人类设计出了按顺序排列好的 n n n 件武器&#xff0c;其中第 i i i 件武器的攻击力为 a i a_i ai​&#xff0c;可以造成 a i a_i ai​ 的伤害。 武器已经排列好了&#xff0c;因此不…

游戏引擎学习第九天

视频参考:https://www.bilibili.com/video/BV1ouUPYAErK/ 修改之前的方波数据&#xff0c;改播放正弦波 下面主要讲关于浮点数 1. char&#xff08;字符类型&#xff09; 大小&#xff1a;1 字节&#xff08;8 位&#xff09;表示方式&#xff1a;char 存储的是一个字符的 A…

JWTUtil工具类

写一个Jwt工具类 导入如下pom.xml依赖 <!--fastjson依赖--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.33</version></dependency><!--jwt依赖--><dependenc…

使用React和Vite构建一个AirBnb Experiences克隆网站

这一篇文章中&#xff0c;我会教你如何做一个AirBnb Experiences的克隆网站。主要涵盖React中Props的使用。 克隆网站最终呈现的效果&#xff1a; 1. 使用vite构建基础框架 npm create vitelatestcd airbnb-project npm install npm run dev2. 构建网站的3个部分 网站从上…

K8S containerd拉取harbor镜像

前言 接前面的环境 K8S 1.24以后开始启用docker作为CRI&#xff0c;这里用containerd拉取 参考文档 正文 vim /etc/containerd/config.toml #修改内容如下 #sandbox_image "registry.aliyuncs.com/google_containers/pause:3.10" systemd_cgroup true [plugins.…

unity小:shaderGraph不规则涟漪、波纹效果

实现概述 在本项目中&#xff0c;我们通过结合 Sine、Polar Coordinates 和 Time 节点&#xff0c;实现了动态波纹效果。以下是实现细节&#xff1a; 核心实现 Sine 波形生成&#xff1a; 使用 Sine 节点生成基本的波形。该节点能够创建周期性变化&#xff0c;为波纹效果提供…

设计模式(四)装饰器模式与命令模式

一、装饰器模式 1、意图 动态增加功能&#xff0c;相比于继承更加灵活 2、类图 Component(VisualComponent)&#xff1a;定义一个对象接口&#xff0c;可以给这些对象动态地添加职责。ConcreteComponent(TextView)&#xff1a;定义一个对象&#xff0c;可以给这个对象添加一…

(附项目源码)nodejs开发语言,212 个性化音乐推荐系统的设计与实现,计算机毕设程序开发+文案(LW+PPT)

摘要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。在现实运用中&#xff0c;应用软件的工作规…

面试时问到软件开发原则,我emo了

今天去一个小公司面试&#xff0c;面试官是公司的软件总监&#xff0c;眼镜老花到看笔记本电脑困难&#xff0c;用win7的IE打开leetcode网页半天打不开&#xff0c;公司的wifi连接不上&#xff0c;用自己手机热点&#xff0c;却在笔记本电脑上找不到。还是我用自己的手机做热点…

数字IC后端低功耗设计实现案例分享(3个power domain,2个voltage domain)

下图所示为咱们社区T12nm A55低功耗实现项目。其实这个项目还可以根据产品的需求做一些改进。改进后项目实现的难度会大大增加。也希望通过今天的这个项目案例分享&#xff0c;帮助到今年IC秋招的同学。 芯片低功耗设计实现upf编写指南&#xff08;附低功耗项目案例&#xff0…