C++ 工程实践(3):采用有利于版本管理的代码格式

2024-01-19 23:48

本文主要是介绍C++ 工程实践(3):采用有利于版本管理的代码格式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

陈硕 (giantchen_AT_gmail)

Blog.csdn.net/Solstice

版本管理(version controlling)是每个程序员的基本技能,C++ 程序员也不例外。版本管理的基本功能之一是追踪代码变化,让你能清楚地知道代码是如何一步步变成现在的这个样子,以及每次 check-in 都具体改动了哪些内部。无论是传统的集中式版本管理工具,如 Subversion,还是新型的分布式管理工具,如 Git/Hg,比较两个版本(revision)的差异都是其基本功能,即俗称“做一下 diff”。

diff 的输出是个窥孔(peephole),它的上下文有限(diff –u 默认显示前后 3 行)。在做 code review 的时候,如果能凭这“一孔之见”就能发现代码改动有问题,那就再好也不过了。

 

C 和 C++ 都是自由格式的语言,代码中的换行符被当做 white space 来对待。(当然,我们说的是预处理(preprocess)之后的情况)。对编译器来说一模一样的代码可以有多种写法,比如

foo(1, 2, 3, 4);

foo(1,

    2,

    3,

    4);

词法分析的结果是一样的,语意也完全一样。

对人来说,这两种写法读起来不一样,对与版本管理工具来说,同样功能的修改造成的差异(diff)也往往不一样。所谓“有利于版本管理”,就是指在代码中合理使用换行符,对 diff 工具友好,让 diff 的结果清晰明了地表达代码的改动。(diff 一般以行为单位,也可以以单词为单位,本文只考虑最常见的 diff by lines。)

这里举一些例子。

对 diff 友好的代码格式

1. 多行注释也用 //,不用 /* */

Scott Meyers 写的《Effective C++》第二版第 4 条建议使用 C++ 风格,我这里为他补充一条理由:对 diff 友好。比如,我要注释一大段代码(其实这不是个好的做法,但是在实践中有时会遇到),如果用 /* */,那么得到的 diff 是:

diff --git a/examples/asio/tutorial/timer5/timer.cc b/examples/asio/tutorial/timer5/timer.cc
--- a/examples/asio/tutorial/timer5/timer.cc
+++ b/examples/asio/tutorial/timer5/timer.cc
@@ -18,6 +18,7 @@ class Printer : boost::noncopyable
loop2_->runAfter(1, boost::bind(&Printer::print2, this));
}
+  /*
~Printer()
{
std::cout << "Final count is " << count_ << "/n";
@@ -38,6 +39,7 @@ class Printer : boost::noncopyable
loop1_->quit();
}
}
+  */
void print2()
{

从这样的 diff output 能看出注释了哪些代码吗?

如果用 //,结果会清晰很多:

diff --git a/examples/asio/tutorial/timer5/timer.cc b/examples/asio/tutorial/timer5/timer.cc
--- a/examples/asio/tutorial/timer5/timer.cc
+++ b/examples/asio/tutorial/timer5/timer.cc
@@ -18,26 +18,26 @@ class Printer : boost::noncopyable
loop2_->runAfter(1, boost::bind(&Printer::print2, this));
}
-  ~Printer()
-  {
-    std::cout << "Final count is " << count_ << "/n";
-  }
+  // ~Printer()
+  // {
+  //   std::cout << "F

这篇关于C++ 工程实践(3):采用有利于版本管理的代码格式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/624123

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

JDK21对虚拟线程的几种用法实践指南

《JDK21对虚拟线程的几种用法实践指南》虚拟线程是Java中的一种轻量级线程,由JVM管理,特别适合于I/O密集型任务,:本文主要介绍JDK21对虚拟线程的几种用法,文中通过代码介绍的非常详细,... 目录一、参考官方文档二、什么是虚拟线程三、几种用法1、Thread.ofVirtual().start(

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

springboot依靠security实现digest认证的实践

《springboot依靠security实现digest认证的实践》HTTP摘要认证通过加密参数(如nonce、response)验证身份,避免明文传输,但存在密码存储风险,相比基本认证更安全,却因... 目录概述参数Demopom.XML依赖Digest1Application.JavaMyPasswo

Java 线程池+分布式实现代码

《Java线程池+分布式实现代码》在Java开发中,池通过预先创建并管理一定数量的资源,避免频繁创建和销毁资源带来的性能开销,从而提高系统效率,:本文主要介绍Java线程池+分布式实现代码,需要... 目录1. 线程池1.1 自定义线程池实现1.1.1 线程池核心1.1.2 代码示例1.2 总结流程2. J

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②