C++本身作为面向对象语言,首先介绍下面向对象一般涉及到的开发原则。

一、面向对象开发原则

1、依赖倒置原则:

针对接口编程,依赖于抽象而不依赖于具体,抽象(稳定)不应依赖于实现细节(变化),实现细节应该依赖于抽象,因为稳定态如果依赖于变化态则会变成不稳定态。

2、开放封闭原则:

对扩展开放,对修改关闭,业务需求是不断变化的,当程序需要扩展的时候,不要去修改原来的代码,而要灵活使用抽象和继承,增加程序的扩展性,使易于维护和升级,类、模块、函数等都是可以扩展的,但是不可修改。

3、单一职责原则:

一个类只做一件事,一个类应该仅有一个引起它变化的原因,并且变化的方向隐含着类的责任。

4、里氏替换原则:

子类必须能够替换父类,任何引用基类的地方必须能透明的使用其子类的对象,开放关闭原则的具体实现手段之一。

5、接口隔离原则:

接口最小化且完备,尽量少public来减少对外交互,只把外部需要的方法暴露出来。

6、最少知道原则:

一个实体应该尽可能少的与其他实体发生相互作用。

7、将变化的点进行封装

做好分界,保持一侧变化,一侧稳定,调用侧永远稳定,被调用侧内部可以变化。

8、优先使用组合而非继承

继承为白箱操作,而组合为黑箱,继承某种程度上破坏了封装性,而且父类与子类之间耦合度比较高。

9、针对接口编程

而非针对实现编程,强调接口标准化。

二、C++开发原则

通过上述面向对象开发原则的理解可以细化到具体C++开发原则。

1、保持简单和直接原则:

保持代码尽可能简单,如果需求需要的话,才在代码中引入灵活的可变点,只添加那些可使整体变得更简单的局部复杂的东西。

2、不需要原则:

总是在你真正需要的时候再实现他们,而不是在你只是预见到你将来会需要他们而去实现,在真正需要的时候再写代码,那时再重构也来得及。

3、避免复制原则:

不要复制,不要重复,这是相当危险的操作,你修改一处代码的时候总能记得去修改另外一处或另外多处你曾经复制的代码吗?

4、信息隐藏原则:

一段代码调用了另外一段代码,调用者不应该知道被调用者代码的实现,否则调用者就有可能修改被调用者的实现来实现某些功能,而这有可能引发其它调用者的bug。

5、高内聚低耦合原则:

类似单一职责原则,明确每个模块的具体责任,尽量少的依赖于其它模块。

6、最少惊讶原则:

函数功能要与函数名字功能一致,难道你要在一个getter()函数去更改成员变量的值吗?

7、更干净原则:

离开露营地的时候,应让露营地比你来之前还要干净,当发现代码中有需要改进或者风格不好的地方,应该立刻改掉,不要care这段代码的原作者是谁,也不要care这是谁的模块,代码所有权是集体的,每个团队成员在任何时候都应该可以对任何代码进行更改和扩展。

三、注重单元测试

重要性就不多说了,防患于未然,构建大型系统尤其需要进行单元测试,保证代码质量,可以防患于未然。

一般都讲究测试驱动开发,开发一个功能首先要想好怎么测试,先把测试代码写好,再去开发对应的需求。通过单元测试也有利于开发者更好的进行接口的设计,主要说下良好的单元测试的原则。

1、单元测试的原则

保证单元测试的代码的质量,单元测试的代码也是代码,不应该和产品代码区别对待,而且单元测试的代码再写出bug更影响测试效率。

2、单元测试的命名

每个测试单元需要根据具体测试内容进行相应的命名,方便定位分析问题,好的命名如果出现问题时通过测试单元的名字基本就可以定位问题。

3、保证单元测试的独立性

每个测试单元都是独立的,不依赖于其它测试单元,不要构建测试单元的上下文,上面的测试单元出问题影响到下面的单元测试的设计是很不友好的。

4、尽量保证一个测试单元使用一个断言

保证测试单元内部的一个相对独立性,上面的断言阻碍了下面的断言测试也是不好的设计。

5、保证单元测试环境的独立

保证每个测试单元都有独立的环境,不依赖于其它环境,每个测试单元都要是个独立的可运行的实例,每个单元测试结束后记得清理环境。

大图模式

6、没必要都做单元测试

没必要对第三方库和外部系统做单元测试,只对自己写的代码进行测试。

7、单元测试尽量不要涉及数据库

数据库的状态是全局的,测试不能保证独立性,而且数据库的访问也是缓慢的,影响单元测试的速度,如果真的需要可以模拟数据库在内容中进行测试,其实通常是在系统集成和系统测试级别时去测试数据库。

8、测试代码与产品代码

不要混淆测试代码和产品代码,产品代码中不应依赖测试代码。

9、测试必须要快速执行

确保秒级别,大型系统的单元测试也就几分钟而已,单元测试不要访问数据库、磁盘、网络等外设。

10、找一些测试替身

例如有些数据需要通过网络获取,那可以利用依赖注入做一个网络替身的类模拟这些数据的产生,可以研究研究Google mock。

四、良好的命名

无论是什么语言,函数和变量的良好命名都是很有必要的,通过函数的名字我们就可以知道这个函数里代码的作用,而不是通过写注释。

1、文件命名

文件名字要全部小写,中间用_相连,后缀名为.cc和.h

2、类型命名

类型名称的每个单词首字母均大写, 不包含下划线: MyExcitingClass, MyExcitingEnum.

3、变量命名

不要将变量的类型在名字中体现,这样以后变量类型改变的话还需要去改动变量名,充分利用IDE的功能,变量 (包括函数参数) 和数据成员名一律小写

4、常量命名

声明为 constexpr 或 const 的变量, 或在程序运行期间其值始终保持不变的,

5、函数命名

常规函数使用大小写混合, 取值和设值函数则要求与变量名匹配:

MyExcitingFunction(), MyExcitingMethod(), my_exciting_member_variable(), set_my_exciting_member_variable().

6、枚举命名

和常量一致

7、Tip:

除非像swap函数里tmp那种一目了然,否则不要搞无意义的命名,函数名变量名字宁可特别长也要写清楚究竟是什么意思,不要用缩写,一个变量尽量在临近使用前才定义,可读性强也可更好利用cpu cache。

五、编辑器

团队可以统一使用相同的编辑器,个人目前使用的是VS Code编辑器,同时每个项目使用统一的.clang_format文件,统一规范代码格式,所有的换行符都要用LF格式,不要用CRLF格式,在右下角可以设置。

个人的.clang-format文件如下,是在google风格的基础上做了些修改:

六、编码规范要点总结

每个头文件都要使用#define避免被重复引用

大图模式

或使用#pragma once,而#define方式更通用

1、鼓励在 .cc 文件内使用匿名命名空间或 static 声明. 使用具名的命名空间时, 其名称可基于项目名或相对路径. 禁止使用 using 指示, 禁止使用内联命名空间(inline namespace)

2、一行尽量不要超过120个字符,一个函数尽量不要超过40行,同时一个文件尽量控制在500行内.

3、所有的引用形参如不做改动一律加const,在任何可能的情况下都要使用 const或constexpr

4、new内存的地方尽量使用智能指针,c++11 就尽量用std::unique_ptr替代std::auto_ptr

5、合理使用移动语义,减少内存拷贝,参考左值引用、右值引用、移动语义、完美转发,你知道的不知道的都在这里

6、禁止使用 RTTI,尽量在编译期间就确定参数类型,不要搞运行时识别typeid这种代码

7、使用 C++ 的类型转换, 如 static_cast<>(). 不要使用 int y = (int)x 或 int y = int(x) 等转换方式

8、明确使用前置++还是后置++的具体含义,如不考虑返回值,尽量使用效率高的前置++ (++i)

9、不要使用uint类型,如果需要使用大整型可以考虑int64,否则类型的隐式类型转换会带来很多麻烦

10、如无特殊必要不要使用宏,可以考虑使用const或constexpr替代宏,宏的全局作用域很麻烦,如果非要用在马上要使用时才进行 #define, 使用后要立即 #undef

11、google文档说一定不要用宏来控制条件编译(但是我自己还没有查到不用宏如何控制条件编译,或许就不要搞条件编译)

12、尽可能用 sizeof(varname) 代替 sizeof(type).使用 sizeof(varname) 是因为当代码中变量类型改变时会自动更新. 您或许会用 sizeof(type) 处理不涉及任何变量的代码,比如处理来自外部或内部的数据格式,这时用变量就不合适了

13、类型名如果过长的话可以考虑使用auto关键字

14、注释统一使用 // ,不要通过注释禁用代码,擅用git,不要为易懂的代码写注释

15、写完代码后记得format,VS Code(windows快捷键)shift + alt + F ,每个项目最好都有统一的.clang_format文件。

16、使用C++的string和stream替代C语言风格的char*,使用std::ostream和std::cout替代printf()、sprintf()等

17、尽量使用STL标准库的容器而不是C语言风格的数组,数组的越界访问之类当时是不会报错的,反而可能弄脏堆栈信息,导致奇奇怪怪难以排查的bug

18、可以更多的使用模板元编程,尽量多的使用constexpr等编译器计算,编译器是我们的好搭档,个人认为模板元编程以后会是C++的主流技术

19、可以考虑更多的使用异常处理方式,而不是C语言风格的errno错误码等,这里可以参考你的c++团队还在禁用异常处理吗?

C++难吗?好学吗?C++到底怎么样?相关推荐

  1. 入门Python难不难?零基础到底要怎么学Python?

    近几年的Python编程发展得非常好,又因为人工智能的发展而发展.入门Python难不难?零基础到底要怎么学Python?本文,小分享入门Python需要掌握的知识. 1.数据库:Python在数据库 ...

  2. 宽和窄俯卧撑哪个更难_窄距俯卧撑到底该多窄?

    窄距俯卧撑到底该多窄? 俯卧撑是地球上最广泛的健身动作,它动作简单,随处可练,而且效果俱佳(能有效的训练我们上肢肌群以及和核心力量) 其中俯卧撑又有很多的变化方式,不同的变化都会给我们的肌肉但来不一样 ...

  3. dsge模型难做吗_DSGE模型到底有用吗?

    有个鸟用!!! 本人硕士毕业以后就职于国内某宏观调控部门,日常工作之一就是搞模型.做预测.由于美国和欧洲等国家的政策部门有一大批人都在研究这个,并且做出了不错的成果,因此北京的的领导提出,作为大国宏观 ...

  4. 计算机教育二级难吗,计算机二级考试到底难不难 好通过吗

    计算机二级考试里同学们并不遥远,基本每一个学生在大学时都会选择报名计算机二级考试.对于绝大部分考生来说,计算机考试都是不难的,而且计算机考试的通过率相对来说也是比较高的. 计算机二级考试难吗 计算机二 ...

  5. 嵌入式Linux驱动难?到底难在哪?

    驱动入门难在:如何通过自己的学习能力搭建起环境,并理解一个LED驱动. 深入驱动难在:对内核的理解,对特定协议的认识. 最近看到论坛和群里一些人在说驱动难,个别人提出提供的入门资料还是难以入门.作为嵌 ...

  6. 史上最难的大学专业 计算机 土木建筑 医学,大学最易挂科的专业,智商不够别报考,不然很难毕业!...

    原标题:大学最易挂科的专业,智商不够别报考,不然很难毕业! 今天向学霸进军给高考生和家长们说一说"大学里最容易挂科专业排行榜",要更加努力哟! 医学专业 每逢期末考试 医学专业应该 ...

  7. 计算机科学和物理哪个难,据说这是期末考试难度最大的15个专业,你上榜了吗?...

    原标题:据说这是期末考试难度最大的15个专业,你上榜了吗? 各位同学们 告诉大家一个好消息 寒假快来了,所以 期末考试还会远吗 是"学霸"还是"学渣" 成败就在 ...

  8. 最难学的10大编程语言排行榜,Java只排第三,第一出乎意料

    2018年12月的TIOBE编程语言排行榜已经出炉,Python重回前三,Go语言跌出前十,Visual Basic.NET涨幅明显,保持第五名. TIOBE排行榜是根据互联网上有经验的程序员.课程和 ...

  9. 一切未晚——七公主后花园的成立

    研三了,开始找工作了,才发觉自己是如此迷茫,产品经理?运营?测试?开发?如果自己都不能定下来一个方向,那又怎么能全力以赴地前进呢?经过多番思索,其实编程也不是那么地难,关键是自己的心态得摆正,如果从内 ...

  10. 大学计算机基础挂了能毕业吗,大学挂科率最高的十个科目,你中枪了吗?

    原标题:大学挂科率最高的十个科目,你中枪了吗? 大学挂科率最高的十个科目 期末考试快到了,对于大学的同学来说, 挂科这一专有名词是再熟悉不过的了. 正所谓,问世间"挂科"为何物, ...

最新文章

  1. sde表空间无法导入数据和编辑
  2. Zookeeper_zkClientListener讲解
  3. 生成目录树CMD命令(bat文件)
  4. Android—内存泄漏、GC及LeakCanary源码解析
  5. HALCON示例程序measure_metal_part_id.hdev使用xld边缘拟合检测零件加工是否合格
  6. Console-算法-递归算法示例
  7. [JS-BOM]BOM_Location地址栏对象
  8. android 三星 白色,时尚实用都拥有 白色Android手机盘点
  9. C++socket编程(八):8.1 UDP讲解,用户数据报协议
  10. Riverbed收购Mazu Networks巩固领导者地位
  11. TensorFlow基础篇(三)——tf.nn.softmax_cross_entropy_with_logits
  12. WCF入门(八)---WCF服务绑定
  13. Jmeter安装步骤
  14. 《说服力》读后总结摘录
  15. windows10电脑连接小爱音箱(完美解决连接上无声音)
  16. 盘点一份JS逆向代码转换为Python代码的教程
  17. 服务器ldb文件可以删除,Access数据库锁死,出现.ldb文件解决办法
  18. CTFhub备份文件下载
  19. 多个div水平横向排列
  20. 【Response】

热门文章

  1. [转载] Python 学习笔记 迭代器和生成器
  2. [转载] java 中 date类型详解
  3. [USACO5.1] Musical Themes
  4. C#方法的六种参数,值参数、引用参数、输出参数、参数数组、命名参数、可选参数...
  5. 设计模式之---解释器模式
  6. 2015 圣诞 限免软件分享
  7. [转]麻省理工学院(MIT)研究生学习指导[上]
  8. 安装 Visual Studio Async CTP
  9. 陈天桥:为何总是半夜惊醒?《前程密码》
  10. K210系列第一个示例程序