C++ Coding Guidelines

一、命名规则

  1、class、struct、typedef以大写字母开头: 

1 // Wrong
2 class myClass
3 {
4 
5 
6 // OK
7 class MyClass
8 {

 2、变量以 作用域+下划线+变量名 命名:

s_:静态变量、单例

k_:全局常量

m_:其他类变量

1 // WRONG
2 bool m_NotMainCharacter;
3 bool m_Redraw; 
5 
6 // OK
7 bool m_IsMainCharacter
8 bool m_HasToRedraw

本地变量使用小写字母开头

1 void Function(...) {
2        float  myLocal1;
3        int    currentStep = 0;
4        ...
5 }

  3、函数:1 使用大写字母开头。2 如果函数返回的值是函数内通过分配得到的,必须清晰地使用Allocate , Create等来命名。

// WRONG
Data* GetData()
{
       return new Data;
}


// OK
Data* AllocateData()
{
       return new Data;
}

Get/Set 直接地访问一个成员时使用Get/Set 来命名。

如果函数需要做额外的任务、做搜索等等,不要使用Get/Set 。

Getxxx函数应该返回一个已经计算好的、已经存在的成员。 

Compute/Find 需要经过冗长的计算时。

Initialize 做初始化一个对象时。

Create/Allocate 创建一个新对象时。

对于功能互补的函数使用互补的名字,start/end、pause/resume、show/hide、add/remove等。

 

函数没必要返回值时,不需要返回。例如函数总是返回true时,不需要返回一个bool。

 1 // Useless
 2 bool Player::IncreaseHealth(u32 iHealth)
 3 {
 4        m_Health += iHealth;
 5        return true;
 6 } 
 8  
 9 
10 // OK
11 void Player::IncreaseHealth(u32 iHealth)
12 {
13        m_Health += iHealth;
14 }

函数参数应当和本地变量明显的区分,i_ 输入参数,o_ 输出参数,io_ 可被改变的输入参数。

1 // Ambigous
2 void Function1(const string& arg1, float& arg2, string& returnVal)
3 {
4 
5 // OK
6 void Function1(const string& i_Arg1, float& io_Arg2, string& o_ReturnVal)
7 {

二、编码结构

  1、类:

  命名空间

尽量少用。命名空间可以避免两个库的名字冲突,但如果使用太多级,会增加混淆。

1 在每个主模块中使用至多1个命名空间。

2 使所有类属于同一个命名空间。

  类的数量

每个.h和.cpp里只有一个类。如果不是必须,不要在头文件里#include ,如果在函数或者指针中使用了其他类,在文件里使用前置声明。

 1 // WRONG
 2 #include "MyClassB.h"
 3 #include "MyClassC.h"
 4  
 5 class MyClassA {
 6 public:
 7        void SomeFunction(const& MyClassB);
 8  
 9 protected:
10        MyClassC* m_Member;
11  
12 };
13 
14 
15 // OK
16 // In MyClassA.h
17  
18 // Forward declaration
19 class MyClassB;
20 class MyClassC;
21  
22 class MyClassA {
23 public:
24        void SomeFunction(const& MyClassB);
25  
26 protected:
27        MyClassC* m_Member;
28 };
29 
30 
31 //-------------------------------
32 // And in MyClassA.cpp
33 #include "MyClassA.h"
34 #include "MyClassB.h"
35 #include "MyClassC.h"
36  
37 void MyClassA::SomeFunction(const& MyClassB)
38 {
39        ...
40 }

源文件里,头文件的引用顺序:

1 #include "precomp.h" // Module header / Precompilation header
2  
3 #include "MyClassA.h" // Current Cpp file header
4 #include "OtherClass1.h" // other headers needed
5 #include "OtherClass2.h"
6 #include "OtherClass3.h"
7  
8 #include <stdio.h> // System headers

  构造函数

在构造函数里尽量初始化所有成员,并且尽量使用初始化列表。

绝不要在构造函数里使用memset 。

 1 // make sure to initialize all variables
 2 Object::Object():
 3  
 4 {
 5        m_member1 = 0;
 6        m_member2  = false;
 7        ......
 8 }
 9 
10 
11 // but prefer this way..
12 Object::Object(): m_Member1(0), m_Member2(false)
13 {
14 ......
15 }
16 
17 // NEVER DO THIS :
18 class Object {
19        ...
20        std::string m_Name;
21 }
22  
23 Object::Object()
24 {
25        memset(this,0,sizeof(Object));
26 }

如果有几个可能矛盾的构造函数,显式的声明他们。

避免在构造函数里分配内存,使用分开的 Init/Uninit或Create/Destroy来分配、回收内存。

  析构函数

如果类里有虚函数或者从一个虚类里继承下来,那,那么一定要声明为虚析构函数。

避免在析构函数里释放内存,内存应该提前被释放。

如果有内存分配,使用assert。

 1 // OK
 2 MyClass::~ MyClass () {
 3        ....
 4        ASSERT (m_Buffer == 0);
 5 }
 6 -          Always assign pointers to 0 after deleting them
 7 
 8 
 9 // WRONG
10 void ReleaseMemory() {
11        delete m_Buffer;
12 }

  2、函数

 

posted on 2015-04-24 14:36  天驱  阅读(393)  评论(0)    收藏  举报

导航