S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

编码规范

Posted on 2010-09-13 19:04 S.l.e!ep.¢% 阅读(4017) 评论(1)  编辑 收藏 引用 所属分类: Team
本文参考资料:
原版:http://1code.codeplex.com/releases/view/51868#DownloadId=148423
译版:http://1codechs.codeplex.com/releases/view/51227#DownloadId=148734


原则:
(1) 团队风格统一,明确规则,提高可读性

1. 字符串类问题

std::wstring
std::string
tstring(TCHAR版本的std::string)

TCHAR
char*
wchar*

char[]
wchar[]

LPCTSTR
LPTSTR

xxstring(自己封装的string类)

其它库的 string

""
L""
_T("")

Format() 问题

无论采用哪种string, 是否采用UNICODE,都要规定好;
  
2. 宏命名规范
1. 所有字母大写
2. 单词之间用_分隔

3. BOOL 还是 bool?
   TRUE or true?  FALSE or true?

4.名字空间滥用?
1. 一个Project只需要一个NameSpace 或 ProjectName.io.xxxxx 的形式

5. 代码跨平台兼容?

6. API函数前面的 :: ?
1. 用于区分系统API函数与本地函数

7. 函数命名?
1. 采用 "动"+"宾"结构,
2. Is + 动 + 宾 结构
3. 意思明确,无歧义

8. 滥用第三方库?

9. 当 if 里只有一条语句时?
if(xxxxxxx)
    语句;
or
if(xxxxxxx)
{
    语句;
}

10. 函数的参数安全性判断 与 多重判断 带来的性能负累?
A函数与B函数有着一样的参数
A函数调用B函数
结果 A函数对所有参数进行了安全性的判断
A函数调用B函数时,又重复作了安全性的判断

11. 注释规范?
1. 文件头注释?
2. 函数注释?
3. 函数内注释?

12. 所有返回值都需要处理,即使你不想理它,也要给它加上 UNREFERENCED_PARAMETER 宏
#define UNREFERENCED_PARAMETER(P) (P)

13. 每个函数都会有执行失败的时候(虽然它可能失败的机率是万分之一)但也请小心处理它

14. 关于其它命名空间里函数的用法?
#include <vector>
using namespace std;

vector<int> vecTest;

or

#include <vector>
std::vector<int> vecTest;

1. 不要在头文件中直接使用 using,特别是 using namespace , 这样别人在引用这个头文件时,会出现“名字污染”,可能涉及整个工程
2. 如果非要使用 using ,在名字空间中使用,这样不用影响到整个工程


15. 类与类之间的依赖?
如:
ProjectName::io::CDir  依赖于  ProjectName::io::CFile
ProjectName::io::CFile 依赖于  ProjectName::util::CString

同个项目中,类与类之间的依赖是可以理解的,但当某天我想用这个Project中的某个类时,依赖的文件太多,不容易单独抽出来使用

16. C++代码中是否应该使用 goto?

17. 模板中的 typename or class?
统一采用 typename

18. delete or delete[] ?
如: char* p = new char[255];
    delete p;
还是
    char* p = new char[255];
    delete[] p;
    ?

19. stringstream or sprintf ?

20. 0 或 NULL?

21. CTime or time_t?

22. UINT32 or unsigned int?

23. 设计模式的滥用?
为了防止设计模式的滥用,未清楚设计模式的意图前,别用它

24. 所有的变量都必须赋予初始值。

25. 关于注释,注释形式不限,但
   (1)每个函数至少要有简要的注释;
   (2)每个参数都要说明其用途


26. int* pValue or int *pValue ?

27. if( NULL != p  ) or if ( p != NULL  ) ?

28. x, y, or width, height?

29. x = (xxx*)y;  or x = dynamic_cast<xxx*>(y) ?
--- 使用后者,因为后者会进行类型判断,如果不一致会抛出异常
vc6.0要支持向下转型要加入GR开关,而这在vc6.0z中是默认关闭的

30. 采用最直观的方式写代码

31. 语句太长?
写法1:
00235     const char *opname =
00236         (op==PJ_ICE_STRANS_OP_INIT? "initialization" :
00237             (op==PJ_ICE_STRANS_OP_NEGOTIATION ? "negotiation" : "unknown_op"));

写法2:
00297         CHECK( pj_dns_resolver_create(&icedemo.cp.factory,
00298                                                              "resolver",
00299                                                              0,
00300                                                              icedemo.ice_cfg.stun_cfg.timer_heap,
00301                                                              icedemo.ice_cfg.stun_cfg.ioqueue,
00302                                                             &icedemo.ice_cfg.resolver) );

写法3:
00397     /* create the instance */
00398     status = pj_ice_strans_create("icedemo",                     /* object name  */
00399                                                  &icedemo.ice_cfg,         /* settings     */
00400                                                  icedemo.opt.comp_cnt,  /* comp_cnt     */
00401                                                  NULL,                          /* user data    */
00402                                                  &icecb,                         /* callback     */
00403                                                 &icedemo.icest)             /* instance ptr */
00404                                                 ;

写法4:
00442     pj_ice_sess_role role = (pj_tolower((pj_uint8_t)rolechar)=='o' ?
00443                                                  PJ_ICE_SESS_ROLE_CONTROLLING :
00444                                                  PJ_ICE_SESS_ROLE_CONTROLLED);


写法5:
00493 #define PRINT(fmt, arg0, arg1, arg2, arg3, arg4, arg5)      \
00494             printed = pj_ansi_snprintf(p, maxlen - (p-buffer),  \
00495             fmt, arg0, arg1, arg2, arg3, arg4, arg5); \
00496             if (printed <= 0) return -PJ_ETOOSMALL; \
00497             p += printed

32. 当 if 语句的只有一条语句时,哪种写法更好?
(1)  if(xxxx)
      {
             xxxxx;
      }
(2) if(xxxx)
            xxxxxx;


-----------------------------------------------------------------------------
1. 概览
1.1. 原则和主旨
高质量代码有如下特质:
(1) 可读性,简单明确, 注释清楚,突出重点, 示例代码
(2) 一致性, 代码风格统一
(3) 正确性, 经过单元测试,pc-lint检测, 符合文档描术要求
(4) 安全性


2.1. 类名以C开头
  
(1)普通类采用 Cxxx 形式 
      例: CSimple
   (2)模板类采用 CxxxT 形式 
      例: CSmartPointorT

2.2. 接口类使用I开头
    (1)接口类指纯虚类
    (2)采用 Ixxx 形式
      例: ILoggable

2.3. 枚举类型命名
    (1)所有字母大写
    (2)以 ENUM_ 开头
    (3)每个单词之间尽量用_分隔
    (4)具体的值不需要 ENUM_ 开头
    例:enum ENUM_DWMNCRENDERINGPOLICY
        {
            DWMNCRP_USE_WINDOWS_TYLE,
            DWMNCRP_DISABLED,
            DWMNCRP_ENABLED,
            DWMNCRP_LAST
        };

2.4. 函数指针类型命名
    (1)所有字母大写
    (2)采用 FN_函数名_TYPE 的形式
   例:
typedef HRESULT (WINAPI *FN_DWMSETWINDOWATTRIBUTE_TYPE)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);

2.5. 函数指针命名
    (1) 采用 pfn函数名 的形式
    例:FN_DWMSETWINDOWATTRIBUTE_TYPE pfnDwmSetWindowAttribute = NULL;

名字缩写规范:
Manager = Mgr
Message = Msg
asynchronous = asyn
event = evt
object = obj
volume = vol
project = prj
calculate = calc

Feedback

# re: 编码规范  回复  更多评论   

2010-09-10 00:14 by nnnn
6. API函数前面的 :: ?
1. 用于区分系统API函数与本地函数

自己的函数就不该取名于api一样阿,就无须::

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理