2. 命名规范
“站在使用者的角度进行命名”
一致的命名可以让程序更清晰,让代码具有更强的说明性,从而提高程序的可读性和可维护性。本规范中描述了最基本的命名规范,包括如何使用大小写,并为软件设计开发中涉及到的基本概念的命名提供参考规范,如名字空间、类型、成员、参数命名等。
2.1. 大小写约定
常见的大小写约定有两种:
PascalCasing和
camelCasing。
√ 要求命名区分大小写。
√ 要求在命名类、结构、接口、函数使用
PascalCasing。
例如,要使用class ColumnInformation而不是class columnInformation或
class COLUMNINFORMATION。
√ 要求宏/常量/类、结构的公有常量时的命名全部使用大写(
推荐:词与词之间使用下划线分隔)。
例如, RAISE_EXCEPTION(exp)
const int MAX_PRIME_NUMBER = 100
class ApplicationInfo
{
public:
static const int PRODUCT_VERSION = 0x01000000;
}
×
不要使用两个或多个仅仅有大小写区别的名字或宏。
√ 要求命名回调函数的类型时候全部使用大写。
例如,使用typedef void (*CLICKINGEVENTHANDLER)()
而不是typedef void (*ClickingEventHandler)()。
√ 要求在命名函数参数、类/结构的成员变量、局部变量时使用
camelCasing。
例如,使用long streamPostion而不是long StreamPostion;
使用long long m_streamPostion而不是long m_StreamPostion。
√ 要求在把由两个字母组成的首字母缩写词全部大写(采用
PascalCasing风格命名时)/小写(采用
camelCasing风格命名时)。
例如,void ProcessIO(std::stream& ioStream)。
void ProcessHtml(std::stream& ioStream)。
√ 要求在把由三个或三个以上字母组成的首字母缩写词全部大写(采用
PascalCasing风格命名时)/ 全部小写(采用
camelCasing风格命名时)。
例如,xmlTag,XMLReader。
2.2. 通用命名约定
√ 要求命名要有意义,大小写相间,可以让人顾名思义,一目了然。
例外:循环变量i,j,k...的命名
l
推荐
不要过度使用
匈牙利命名法。
例如,在SDK的接口中尽量不要使用匈牙利命名法以确保这个命名对于Windows和非Windows(如Linux/Unix)程序员都是公平的。
×
不要使用那些没有被普遍接受的缩写。
例如,不要使用SI来表示没有被广泛接受的名词Spread Item,
不要使用GetNthItem,使用GetItem
×
不要在标识符中使用“Ex”而要使用数字来区分相同
API的不同版本
例如,使用void ShowMessage2()而不是void ShowMessageEx()来命名
void ShowMessage()的第二个版本。
l
推荐不要使用“Ex”来区分同一版本的表示两个功能相近的
API,最好使用一个更加有意义的名字。
例如,
void DoCommand ()
void DoCommandEx()//不好
void DoPluginCommand()//好,意义更加明确
×
不要在使用“Ex”来区分同一/不同版本的
类/结构,最好使用一个更加有意义的名字。
例如,
class StreamPosition{…}
class StreamPositionEx{..}//不好
class FixedStreamPosition{..}//好
class DynamicStreamPosition{..}//好
2.3. 名字空间的命名
√ 要求全部使用小写来命名名字空间。
例如,graph,dom,v12sys::io,v12sys,v12sys:: text
×
不要使用已有的通用的名字来命名名字空间。
例如,std
×
不要使用相同的名字来命名名字空间和位于此名字空间的类型。
例如,不要在graph命名空间里定义类Graph。
2.4. 类型(类、结构、接口、枚举、typedef)的命名
√ 要求
使用名词或名词词组来给类型命名。
例外:少数情况可使用形容词(词组)来给类型命名。
例如,
class PageSetting,class Document //好
class VCodeParser //好
class ParseVCode //不好
√ 要求
采用PascalCasing
大小写风格。
例外:typedef。
l
推荐使用typedef命名基本类型时,全部使用大写
例如,typedef int VINT32
typedef long VOBJID32
√ 要求让接口的名字以字母I开头。
例如,interface ICopyable,interface IApplication,interface IObserverManager。
2.4.1. 泛型类型的命名
√ 要求
使用名词或名词词组来给泛型类型命名,采用PascalCasing
大小写风格。
例如,
template<typename TInput , typename TOutput >
class Converter //好
√ 要求命名泛型参数使用范式 Txxx,不要使用_Txxx或其他范式。
template<typename TInput , typename TOutput >
class Converter //好
template<typename _TInput , typename _TOutput >
class Converter //不好
√ 要求使描述属性的名字来命名泛型参数。
例外:如果泛型类型只有一个参数,而且类型参数只有一个字母,使用T类命名参数类型。
例如,template<typename T> bool ToString(const T& value)
template<typename TSession> class SessionChannel(const TSession & session)
2.4.2. 枚举类型的命名
√ 要求
使用名词或名词词组来给枚举类型命名,采用PascalCasing
大小写风格。
例如,enum kFileType,enum kExportType
×
不要给枚举类型的名字添加“Enum“、“Flag”、“Flags”后缀。
例如,不要定义enum kFileTypeEnum,enum kExportTypeFlags
√ 要求为枚举类型的名字使用“k”前缀。
√ 要求枚举类型值的名字=枚举类型的名字+"_"+枚举类型值的真实意义的名字。
例如,enum kFileType
{
kFileType_None,
kFileType_Ansi,
kFileType_Unicode
}
例如,long g_s_VisitTimes,unsigned int g_s_CurrentMessage
√ 要求给全局变量的命名加上g_前缀。
2.5. 成员的命名
2.5.1. 函数的命名
√ 要求
使用动词或动词词组来命名函数。
例如,Track,ShowMessage,GetItem
√ 要求用于设置程序状态的函数的名称=Set+表示程序状态的名词、名词词组或形容词。
例如,SetDirty,SetChangeState,SetWindowText
√ 要求用于获取程序状态的函数的名称=Get+表示程序状态的名词、名词词组或形容词。
例如,int GetChangeState() const,int GetEnabled() const
l
推荐用于获取程序状态且
返回值为布尔值的函数的名称=Is/Can/Has/Contain/Include等+表示程序状态的名词、名词词组或形容词。
例如,bool Contain(int item) const,bool HasUnicodeCharacter
bool IsChanged() const
2.5.2. 事件的命名
√ 要求命名事件类型(即回掉函数)的时候全部使用大写。
例如,typedef void (*BUTTONEVENTHANDLER)();
√ 要求使用动词或动词词组来命名事件
例如,typedef void (*BUTTONEVENTHANDLER)();
BUTTONEVENTHANDLER Clicking;
BUTTONEVENTHANDLER Clicked;
√ 要求使用现在时和过去时来区别正在发生(之前)和已经发生(之后)的事件。
例如,typedef void (*BUTTONEVENTHANDLER)();
BUTTONEVENTHANDLER OnBeforeClick;//不规范
BUTTONEVENTHANDLER OnAfterClick; //不规范
BUTTONEVENTHANDLER Clicking;//规范
BUTTONEVENTHANDLER Clicked; //规范
2.5.3. 字段的命名
√ 要求使用名词或名词短语来命名字段。
例如,std::string m_phone,long m_areaCode
√ 要求给静态字段的命名加上s_前缀。
例如,long m_s_timeElapsed,long g_s_VisitTimes
√ 要求
给私有或受保护的字段加上m_
前缀。
例如,long m_s_timeElapsed
×
不要给公共字段加上m_前缀,公共字段的命名要求采用
PascalCasing风格。
例如,
class PointF
{
public:
static const PointF Empty;//好
…
}
2.6. 全局变量/函数的命名
2.6.1. 全局变量的命名
√ 要求使用名词或名词短语来命名字段。
√ 要求全局变量的命名要求采用
PascalCasing风格。
例如,
long g_s_VisitTime;//好
long g_s_visitTimes;//不好
√ 要求给静态全局变量字段的命名加上s_前缀。
2.6.2. 全局函数的命名
√ 要求给符合成员函数的命名规则。
2.7. 参数的命名
√ 要求命名参数时使用
camelCasing大小写风格。
√ 要求使用具有描述性的参数名。
例如,void ChangePhoto(const std::string& photoFileName,
int photoType)
2.8. typedef
√ 要求常见的typedef遵循下表的规则:
typedef
|
规范
|
typedef std::vector<T> A
|
√ 要求为A添加后缀”Array”,
如typedef std::vector<int> IndexArray;
|
typedef std::stack<T> A
|
√ 要求为A添加后缀”Stack”,
如typedef std::vector<int> OrderStack;
|
typedef std::map<T1,T2> A
std::multimap<T1,T2> A
|
√ 要求为A添加后缀”Map”,
如typedef std:: map<string,string> ConfigMap;
|
typedef std::list<T> A
|
√ 要求为A添加后缀”List”,
如typedef std:: list<string> NameList;
|
typedef std::deque<T> A
typedef std::queue<T> A
|
√ 要求为A添加后缀”Queue”,
如typedef std::queue<string> StudentQueue;
|
typedef std::set<T> A
typedef std::multiset<T> A
|
√ 要求为A添加后缀”Set”,
如typedef std::set<int> PrimeSet;
|