设计心得——作用域处理

一、作用域

作用域(Scope)是什么?其实很简单,就是字面的意思。就是在哪个范围内可以应用。不同的行业都有作用域的概念,它们的概念或多或少的都有不同。即使在计算机编程语言中,不同的语言,作用域的概念也是有所不同的。比如有的语言没有类的概念,有的语言没有名空间。同样,同一个语言在不周的时期或者说不同的版本本也作用域也会有不同,这个都需要开发者引起注意。
作用域一个重要作用就是控制可见性和编程单元(变量、类等)的生命周期,这个非常重要。毕竟,可见性和生命周期都能直接影响代码的安全性和健壮性。

二、C++中的作用域

重点分析一下C++中的作用域。按不同的划分可以有多种的作用域划分:
1、按整体划分
可分为全局作用域和局部作用域。这个好理解,整体作用域是指在整体的可见范围内都可以应用;而局部作用域则只能指定的局部范围内应用。请一定注意,这个全局和局部是相对的,不是绝对的。比如一个文件可能是一个全局,也可能是一个局域,这看程序的设计和结构。
2、按代码定义划分
可分为名空间作用域、类作用域和块(函数)作用域。前二者的划分非常好理解,毕竟都是有明显的特征控制范围的。但块作用域可能对不少程序员理解起来有点麻烦。主要原因在于块作用域的标记{}这对大括号的功能不断的增加变化,有可能让小白们最头疼。同时它代表函数时,内部往往会嵌套,就更让初学者难受。但只要把握了作用域的特点,应用起来还是比较容易看清楚的。
3、按文件划分
如果说整体局部是一种逻辑的存在,代码是内部显示定义的存在,那么文件来划分可以理解成一种形式上类似于物理的隔绝。开发者可以使用static定义静态的作用域,让编程单元只能在本文件中使用。
可能如果按其它的维度划分还有更细的划分情况,这里就不再一一展开。不同的划分情况适应不同的场景,它们之间是综合应用的,不是必然单独一种的。比如一个全局变量可以增加static就成为了一个文件作用域内的全局变量。另外可见性和生命周期与作用域也未必一一对等,比如一个局部静态变量,它的可见性只在局部域内,但生命周期却是全生命周期的。如此等等,开发者一定要引起重视。
作用域其实是接口划分和封装的一个重要的保障,既要保障编程单元的合理可见性和生命周期的安全性(比如使用RAII等),又要保持在某些特殊情况下的连续可见性和全生命周期性(如单例等)。但一个整体的原则是在合理的情况下,作用域要尽可能的小。毕竟作用域越大,被其它单元污染的可能性越大。这种污染,如果只在极少的情况下发生时,往往难于发现和解决。

三、设计中的应用

大家熟知的安全措施诸如加密、接口控制以及最常见的用户名和密码,其实也是一种作用域的控制,只不过它是针对应用层。而这里提到的作用域,是针对代码层的。在前面分析了很多种设计的情况,更多的是倾向于框架的设计。哪怕是到一个函数,一个类,侧重的是由外向内的划分。而作用域,侧更倾向于从内向外划分,即一般先有一个定义单元,然后再考虑它的应用范围。
或者也可以理解为前面的设计更倾向于逻辑上的划分,而作用域更倾向于内容的划分。当然,二者一定不是严格区分的,站在不同的角度上,当然也会有不同的看法。
那么在实际的应用中,就要在具体的场景下考虑是由上至下还是由下至上,或由内到外还是由外到内哪种更便捷、简单,更容易扩展。当然更有可能的是综合应用,不同的层次下或不同的模块中采用不同的方式。
作用域和粒度有相通之处,又有很大的不同。但作用域不光是城墙,还有城门。作用域有可能会需要延展到另外一个作用域,或者说作用域可以通过某种实现达到不同的作用域内。给大家举一个不太恰当的例子,大家就更清楚了,一个函数内的类变量作用返回值返回时,如果开启了优化,则有可能会直接在调用方构造,编译器其实是主动打破了作用域的范围。
打破这种作用域的方法很多,比如刚刚提到的static,lambada表达式的捕获,引用传递等。
也就是说,一定要弄清楚作用域与可见性、生命周期的关系。
基于上面的分析,在设计中就可以能过作用域来灵活的控制编程单元的可见性,并基于不同的情况利用其生命周期来实现一些设计模式和具体的应用。例如刚刚提到的RAII,就是利用局部类变量在析构时释放相关的资源来实现的。
同样,Pimpl也是一种安全的可访问实现,诸如这些通过作用域控制来实现功能的在C++中很多,大家可以留心总结一下。

四、例程

下面看一个简单的例程:


#define flour1 4
constexpr short flour2 = 5;//全局 作用域
static short s_tee = 0;//文件作用域
void testDraw(Point a/*函数原型声明作用域*/);
class A {
public:void Display() {//函数作用域std::cout << "this is test!" << std::endl;this->Print();}//类作用域void Print() { std::cout << "this is print!" << std::endl; }
};
namesapce OK{//名空间作用域
int a = 0;
}
void testInteritance(){//块作用域Parent p;//局部作用域p.eat(100);InheritanceExample ie;ie.eat(200);
}
int main() {testInteritance();auto ret = BigEndian();A *a = nullptr;a->Display();return 0;
}

诸如RAII和单例等的例子,大家翻看前面的例程即可,此处不再重复赘述。

五、总结

简单的东西,往往意味着灵活。因为简单,所以应用的广泛,应用的广泛就意味着应用的场景丰富。不同的场景下的应用就有可能有细节的不同。而细节的丰富恰恰是C++的一个特点,也是为广大开发者觉得不容易把握的地方。
作用域看似简单,但它和代码编写直接结合了起来。往往代码的水平就可以通过作用域的控制窥见一斑。而作用域还有一个特点,即使设计的较差甚至非常差,在一些中小程序中对程序的运行也不会有什么影响。往往就会让大多数中低程序员将其忽视。
简单不代表容易把握,切记!

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

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

相关文章

VC6.0图文安装教程

VC6.0图文安装教程 ​ 1、首先&#xff0c;右击安装包&#xff0c;以管理员身份运行 2、点击下一步 ​​​​ 3、点击下一步 4、选择安装路径&#xff0c;点击下一步 5、点击下一步 6、点击安装 7、安装ing 8、点击完成 至此&#xff0c;安装完成&#xff01;

用户说 | 零基础用通义灵码 AI 程序员开发个人笔记网站

作者&#xff1a;宋镇江&#xff0c;安阳幼儿师范高等专科学校数字媒体技术专业教师 通义灵码是一款基于通义大模型的智能编码辅助工具&#xff0c;支持自然语言生成代码、单元测试生成、代码注释生成等功能&#xff0c;兼容多种主流IDE和编程语言。对于零基础用户&#xff0c…

试验一 mybatis 入门操作

试验一 mybatis 入门操作 一 实验目的 1.掌握mybatis基础操作&#xff0c;包括如何在maven工程中引入依赖&#xff0c;创建mapper文件&#xff0c;核心配置文件&#xff0c;映射文件&#xff0c;并测试对数据库表基本的的CRUD操作&#xff1b; 2.掌握核心配置文件中几个重要标…

使用Gitee Go流水线部署个人项目到服务器指南

使用Gitee Go流水线部署个人项目到服务器指南 前言&#xff01;&#xff01;&#xff01; 本文解决的问题&#xff1a; 你有一台ECS服务器&#xff0c;你在上面部署了一个Java服务也就是一个jar&#xff0c;你觉着你每次手动本地打包&#xff0c;上传&#xff0c;在通过命令去…

LCCI ESG 中英联合认证国际分析师适合的岗位

LCCI ESG中英联合认证国际分析师领域热门岗位大揭秘&#xff01;&#x1f30d; 大家好&#xff01;今天我们来探讨LCCI ESG中英联合认证国际分析师领域的热门岗位&#xff0c;看看是否有适合你的选择。 1️⃣ LCCI ESG中英联合认证国际分析师报告专员&#xff1a;主要负责编制…

Compose 实践与探索十五 —— 自定义触摸

1、自定义触摸与一维滑动监测 之前我们在讲 Modifier 时讲过如下与手势检测相关的 Modifier&#xff1a; Modifier.clickable { } Modifier.combinedClickable { } Modifier.pointerInput {detectTapGestures { } }这里对以上内容就不再赘述了&#xff0c;直接去讲解更复杂的…

【Linux】Makefile秘籍

> &#x1f343; 本系列为Linux的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:【小编的个人主页】 >小编将在这里分享学习Linux的心路历程✨和知识分享&#x1f50d; >如果本篇文章有问题&#xff0c;还请多多包涵&a…

LDAP从入门到实战:环境部署与配置指南(上)

#作者&#xff1a;朱雷 文章目录 一、LDAP 简介1.1. 什么是目录服务1.2. 什么是 LDAP1.3. LDAP的基本模型 二、Ldap环境部署2.1.下载软件包2.2.安装软件2.3.编辑配置文件2.4.启动服务 一、LDAP 简介 1.1. 什么是目录服务 目录是专门为搜索和浏览而设计的专用数据库&#xff…

《C++智能指针:建议使用 make_shared 代替 shared_ptr》

《C 智能指针&#xff1a;长达数十年的血泪史&#xff0c;一步步征服内存泄漏》-CSDN博客 shared_ptr<int> sp1(new int(10)); 这句代码实际存在两个内存开辟&#xff0c;一是开辟我们要托管的内存资源 &#xff0c;二是开辟引用计数的资源&#xff0c;引用技术也是new出…

代码随想录刷题day50|(回溯算法篇)131.分割回文串▲

目录 一、回溯算法基础知识 二、分割回文串思路 2.1 如何切割 2.2 判断回文 2.3 回溯三部曲 2.4 其他问题 三、相关算法题目 四、总结 一、回溯算法基础知识 详见&#xff1a;代码随想录刷题day46|&#xff08;回溯算法篇&#xff09;77.组合-CSDN博客 二、分割回文…

vivo 湖仓架构的性能提升之旅

作者&#xff1a;郭小龙 vivo互联网 大数据高级研发工程师 导读&#xff1a;本文整理自 vivo互联网 大数据高级研发工程师 郭小龙 在 StarRocks 年度峰会上的分享&#xff0c;聚焦 vivo 大数据多维分析面临的挑战、StarRocks 落地方案及应用收益。 在 即席分析 场景&#xff0c…

Springboot的jak安装与配置教程

目录 Windows系统 macOS系统 Linux系统 Windows系统 下载JDK&#xff1a; 访问Oracle官网或其他JDK提供商网站&#xff0c;下载适合Windows系统的JDK版本。网站地址&#xff1a;Oracle 甲骨文中国 | 云应用和云平台点击进入下滑&#xff0c;点击进入下载根据自己的系统选择&…

力扣算法Hot100——128. 最长连续序列

题目要求时间复杂度为O(n)&#xff0c;因此不能使用两次循环匹配。 首先使用 HashSet 去重&#xff0c;并且 HashSet 查找一个数的复杂度为O(1)外循环还是遍历set集合&#xff0c;里面一重循环需要添加判断&#xff0c;这样才不会达到O( n 2 n^2 n2)判断是否进入最长序列查找循…

BlockChain.java

BlockChain 区块链&#xff0c;举个栗子 注意啦&#xff0c;列子里面的hashcode相等&#xff0c;但是字符串是不一样的哦&#xff0c;之前有记录这个问题 String.hashCode()-CSDN博客

visual studio 中导入 benchmark

法一 1.visual studio 中导入 benchmark.lib Shlwapi.lib这两个库 2.预处理宏 BENCHMARK_STATIC_DEFINE vs导入参考 错误提示 没有加入 BENCHMARK STATIC_DEFINE error LNK2001: 无法解析的外部符号 “__declspec(dllimport) int __cdecl benchmark::internal::InitializeS…

java基础之windows电脑基础命令

windows电脑基础命令 windows电脑基础命令快捷键和功能键键盘功能键B:键盘快捷键 DOS命令行的进入方式xp下如何打开DOS控制台&#xff1f;win7下如何打开DOS控制台&#xff1f;win8下如何打开DOS控制台 DOS命令讲解 黑窗口编译文件使用黑窗口运行java程序 windows电脑基础命令 …

Java 第十一章 GUI编程(3)

目录 内部类 内部类定义 内部类的特点 匿名内部类 格式&#xff1a; 内部类的意义 实例 内部类 ● 把类定义在另一个类的内部&#xff0c;该类就被称为内部类。 ● 如果在类 Outer 的内部再定义一个类 Inner&#xff0c;此时类 Inner 就称为内部类 &#xff08;或称为嵌…

uniapp 实现的下拉菜单组件

采用 uniapp 实现, 是一款具备丝滑折叠、展开动画的下拉菜单&#xff0c;支持 vue2、vue3&#xff1b;适配 web、H5、微信小程序&#xff08;其他平台小程序未测试过&#xff0c;可自行尝试&#xff09; 可到插件市场下载尝试&#xff1a; https://ext.dcloud.net.cn/plugin?i…

【一维前缀和与二维前缀和(简单版dp)】

1.前缀和模板 一维前缀和模板 1.暴力解法 要求哪段区间&#xff0c;我就直接遍历那段区间求和。 时间复杂度O(n*q) 2.前缀和 ------ 快速求出数组中某一个连续区间的和。 1&#xff09;预处理一个前缀和数组 这个前缀和数组设定为dp&#xff0c;dp[i]表示&#xff1a;表示…

ubuntu部署运行xinference全精度对话deepseek本地部署图文教程

前置环境搭建劳请移步往期 source activate 自己环境名启动python3.12环境安装xinference&#xff0c; 按教程敲命令&#xff0c;wheel包与wsl的通用&#xff0c;pip install 包名。 vllm引擎&#xff0c;transform引擎也会顺带自动装上了。 后续操作请参照往期教程。本地部署模…