新规范的目标:

  • 让代码排错更加简单
  • 程序员专心于业务逻辑
  • 将一些错误交给编译器处理
  • 提高代码可维护性
  • 逐步实现插件化

编码

  • 使用array(QT下用QVarLengthArray)代替和vector代替原生数组,除非与外部库交互,否则不要直接操作内存(即暴露data的接口)

    关于array和vector初始化麻烦的问题,在VS2010下使用boost::assign库,在VS2015下则使用list initial的语法

    使用array和vector代替原生数组以后,可以很好找到越界的地方

  • 尽量不要直接操作内存, 如果需要使用内存和字符串操作,尽量使用memset_s, memcpy_s,尽量使用_s结尾的函数

    http://en.cppreference.com/w/c/string/byte

    如果需要初始化数组,使用int a[COUNT] = {0}这种语法(但实际上尽量不要直接使用原生数组)

  • 在进行memory操作的时候,需要使用is_pod验证下变量类型是否pod类型

  • 使用STL的算法代替手写的算法,平常用到的算法STL里面或者QT的算法模块里面都有

    http://en.cppreference.com/w/cpp/algorithm

  • 构造函数一定要初始化C原生类型的数据成员

  • 使用C++风格的转换,不要用C语言方式的转换

    dynamic_cast,当继承树不一样的时候,编译器将会报错,或者转换失败,原生的C语言编译正确并且转换正确

    static_cast,会有转换类型检查,比如子类往父类强转,编译期检查

  • 使用QVariant代替void*

    当进行强转错误的时候,QVariant能直接返回错误的数值

  • 使用强枚举

    便于查看代码

    如果传入错误,可以直接让编译器报错

  • 编写测试,系统检测架构图,然后 将测试用例自动化

  • 分离数据和界面

  • 常用的宏定义,放在Global里面,类似于qt_global文件

    IOCEAN里面经常会有重复的宏定义,比如PI,比如无效的HDG,需要防止这种情况

  • 多用const

    const的类成员函数,告诉使用者这个函数将不会对类成员进行改变,在写代码如果有改变,也能直接报错

    const的参数

    const的引用参数

    在计算出一些临时的参数后,如果确定这个参数不会再改变了,也建议用const

  • 使用Q_ASSERT, assert, static_assert断言处理逻辑上不可能出现的情况

    如果已经使用Q_ASSERT,表示这种情况下不需要测试

    在发送网络的数据的时候,有时候发送的是纯二进制数据,但是后续用户可能会在这个数据加入非POD数据,可以使用static_assert( std::is_pod<>::value) 来确保这个结构体是纯二进制数据

  • 字符串和数据结构库统一使用QT的库,比如QLIST,QVector,而非std::list,std::vector

    为了防止混用

    与QT库比较好结合

  • 信号连接使用QT5的新语法

资源管理

  • 使用scoped_pointer和shared_pointer来代替原始指针

    专注业务编写,而非内存管理以及排错

    便于调试,如果是局部变量的指针,在release会直接被优化成地址,无法显示信息,如果是shared_pointer或者scoped_pointer则不会

  • 所有创建的线程,都要设置名称,方便查询线程的用处

  • 资源应该遵循谁申请谁释放的原则,不应该把一个资源胡乱传递(将会导致最后资源不知道谁释放谁持有)

    • 如果资源需要转移,尽量使用MOVE来进行转移,然后用RAII来释放
  • CPP里面的模块变量使用static const而不是只有const声明

  • 使用static const代替宏定义

代码结构

  • 记录log,log不仅仅是开发的时候调试使用,更是在用户机子上分析错误的重要工具,现在我们大部分的log都是维持在debug级别,应该要多编写warning和error级别的log

    由于很多情况下,一些错误的情况无法复现,也无法分析,特别在部署到用户机子上以后,很难到现场排查

    一开始不一定要记录log,根据自己的经验判断是否需要log,但是随着开发进度的增加,会出现一些莫名其妙的错误,比如网络不稳定,内存不稳定导致问题,排查完问题后,在发生问题的根源记录下log

    1. 有一个问题,经常会掉线,因为网络有时候波动会比较大,写数据库会很慢,这个时候如果新客户端连上去后会发送所有的数据,将会导致心跳包处理不及时,客户端会主动断开,排查完原因后,在初始化发送数据的地方编写一段代码,当初始化超过一定的时间后,将会记录一个warning,下次发生这种情况,直接通过log来排查分析

    2. 有时候一些模块因为需要排队处理数据,但是数据处理不即时,导致数据一直存储在buffer里面,但是按照正常情况下,不应该发生这种情况。排查完问题以后,应该在插入buffer的地方写一个判断代码,当buffer大于多少后,给出一个warning

  • 底层数据管理类不要直接暴露内部的情况,并且将对底层数据操作的算法提取出来写在管理类里面,而不是大家都写一个相同的算法

    在代码重构阶段,一旦底层数据直接暴露,那么将会很难修改

    一旦代码有相关联的模块,这种方式比较好处理,比如删除元素,需要把相关联的数据都删除掉,如果没有把deleteTarget封装成一个接口,那么需要查找所有相关联的代码,把这个业务的代码再写一遍

    防止大部分人写了相同的代码

  • 所有数据只有一份,包括内存里面的数据和网络消息,现在一个数据结构经常定义了2-3份数据,包括内存里面的,序列化成网络消息的

  • 组合,继承与接口设计

    继承要保证是一个is-a的类型,即保证同样的逻辑操作可以用在同一个接口上面,而不需要进行大量的转换,如果逻辑操作出现大量的类型转换,考虑是否继承出现了问题

  • 信号

    将业务组合成一个函数,单独的功能写成一个单独的模块,然后在一个函数里面将这些业务组合起来

  • 如果有大量相同的逻辑代码,考虑是否可以提取成一个函数或者模板, 特别是当一个逻辑不会增加依赖的时候

  • 如果使用了大量的dynamic_cast,并且有相同逻辑的代码,考虑是否可以将这个行为抽象成一个接口

工程方案

  • 通用的库弄成一个lib,比如SQL之类的库

  • 非通用的库,但是一些项目里面要用到的,新建一个解决方案,解决方案里面有一个共用的库

待议

  • 多线程,openmp, map-reduce模式

- 语义明确的多线程

  • SQL模块 select(tablename).where("i < 7").and("j > 8").or("x < 2")

  • 使用std::function代理SIGNAL和SLOT的绑定

  • 将不需要制作成索引的数据使用json保存,而不是另外创建一个表然后关联过去

  • 尽量使用designer进行布局

所有人需要了解的C++技术

  • C++11

  • RAII

  • Move语义

C++的一些编程规范的更多相关文章

  1. Batsing的网页编程规范(HTML/CSS/JS/PHP)

    特别注意!!!我这里的前端编程规范不苟同于Bootstrap的前端规范. 因为我和它的目的不同,Bootstrap规范是极简主义,甚至有些没有考虑到兼容性的问题. 我的规范是自己从编程实践中总结出来的 ...

  2. JAVA编程规范(下)

    JAVA编程规范(下) 2016-03-27 6. 代码的格式化 6.1 对代码进行格式化时,要达到的目的 1.     通过代码分割成功能块和便于理解的代码段,使代码更容易阅读和理解: 2.     ...

  3. JAVA 编程规范(上)

    2016-03-20 J120-CHARLIEPAN JAVA 编程规范(上) 1.      应用范围 本规范应用于采用J2EE规范的项目中,所有项目中的JAVA代码(含JSP,SERVLET,JA ...

  4. 使Eclipse符合Java编程规范

    编程规范是很重要的东西,能让团队的代码易于阅读和维护,也便于日后的功能扩展. 工欲善其事必先利其器!作为一个Java程序员,与Eclipse打交道可能是一辈子的事情.将Eclipse设置为符合公司编程 ...

  5. flex+AS3编程规范

    flex+AS3编程规范 Flex+AS3编码规范 http://www.cnblogs.com/jiahuafu/   1.  缩写: 尽量避免使用缩写,使用缩写时尽量和Flex保持一致.但要记住一 ...

  6. Python编程规范(PEP8)

    Python编程规范(PEP8) 代码布局 缩进 对于每一次缩进使用4个空格.使用括号.中括号.大括号进行垂直对齐,或者缩进对齐. 制表符还是空格? 永远不要将制表符与空格混合使用.Python最常用 ...

  7. Python 编程规范-----转载

    Python编程规范及性能优化 Ptyhon编程规范 编码 所有的 Python 脚本文件都应在文件头标上 # -*- coding:utf-8 -*- .设置编辑器,默认保存为 utf-8 格式. ...

  8. JavaScript编程规范

    最近看NodeJS中,有一部分写JS约定俗成的编程规范(附录B,详情参考附件),感觉在实际工作中能用到, 大致意思分享给大家,详情参考附件: 1.缩进:建议两空格 作为Node.js代码的缩进标记: ...

  9. 华为C语言编程规范

    DKBA华为技术有限公司内部技术规范DKBA 2826-2011.5C语言编程规范2011年5月9日发布 2011年5月9日实施华为技术有限公司Huawei Technologies Co., Ltd ...

  10. 中兴软件编程规范C/C++

    Q/ZX 深圳市中兴通讯股份有限公司企业标准 (设计技术标准) Q/ZX 04.302.1–2003      软件编程规范C/C++                               20 ...

随机推荐

  1. 希尔伯特空间(Hilbert Space)是什么?

    希尔伯特空间是老希在解决无穷维线性方程组时提出的概念, 原来的线性代数理论都是基于有限维欧几里得空间的, 无法适用, 这迫使老希去思考无穷维欧几里得空间, 也就是无穷序列空间的性质. 大家知道, 在一 ...

  2. Android Butterknife框架 注解攻略

    一.原理. 最近发现一个很好用的开源框架,蛮不错的,可以简化你的代码,是关于注解的.不多说直接进入使用步骤讲解. 二.步骤. 1.准备阶段,先到官网( http://jakewharton.githu ...

  3. System.Net.Http

    System.Net.Http DotNet菜园 占个位置^-^ 2018-11-10 09:55:00修改 这个HttpClient的学习笔记一直迟迟未记录,只引用了其他博主的博客链接占个位置,但被 ...

  4. unix网络编程 str_cli epoll 非阻塞版本

    unix网络编程 str_cli epoll 非阻塞版本 unix网络编程str_cli使用epoll实现讲了使用epoll配合阻塞io来实现str_cli,这个版本是配合非阻塞io. 可以看到采用非 ...

  5. Linux日常命令使用记录

    scp在跨机器复制的时候为了提高数据的安全性,使用了ssh连接和加密方式,如果机器之间配置了ssh免密码登录,那在使用scp的时候密码都不用输入. 在服务器104.238.161.75上操作,将服务器 ...

  6. PHP+JQuery实现ajax跨域

    jQuery实现ajax跨域 1.dataType:'jsonp'2.type: 'get'3.把要传的参数以url方式传出去  url:'http://gameapi.feiliu.com/lqzg ...

  7. sysbase 笔记

    Alter 在已有数据的表中新增一个字段: ALTER table ciecdb.ciec.eci_mansmfile ADD num int default 0;

  8. 洛谷P2766 最长不下降子序列问题(最大流)

    传送门 第一问直接$dp$解决,求出$len$ 然后用$f[i]$表示以$i$为结尾的最长不下降子序列长度,把每一个点拆成$A_i,B_i$两个点,然后从$A_i$向$B_i$连容量为$1$的边 然后 ...

  9. GitHub 十大 CI 工具

    简评:GitHub 上最受欢迎的 CI 工具. 持续集成(Continuous integration)指的是,频繁地(一天多次)将代码集成到主干. 持续集成工具让产品可以快速迭代,同时还能保持高质量 ...

  10. 1. Shell编程第一讲

    (1)shell 历史: Shell的作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行一条,这种方式称为交互式(Interactive). Shell还有一种执行命令的方式称为批处理( ...