我的C++程序命名规则

我的开发原则

1.错的意外有无数种, 但对的方法只有一个. 只遵循正确的方法运行, 错误的意外不使之矫正, 只是以容错来减少代码量.

2.按事情客观规律办事, 尽量不以个别系统独有的API做. 用也是成体系物理和逻辑上的规划, 减少依赖关系, 增强独立性及普遍性.

3.考虑底层, 国际性等. 先做出成品,再行优化. 不追求华而不实的东西, 只做内秀相关的实用东西. 好用, 方便, 实用, 才是王道.

我的C++程序命名规则

一、逻辑架构

:FSDirectory, _AtomNode_c - 对于长类名不进行后缀命名处理,对于短类名或易混淆[如用于静态等]的类名加后缀_c

抽象接口:ITweaker, IInjecter, IComparer 或 _Collection_i, _DocumentAction_i - 可以用前缀I表示接口类型,否则加_i表示私有抽象接口类型
* 接口的定义:纯虚类,无变量私有或保护成员,表示一个动作或一组动作的标准。用于表达一个规范准则,常用于多重继承实现。使用接口必须通过指针实现。

结构体:TColor, TRectangle, _WindowInfo_st - 使用T加大写结构体名前缀实现

枚举类型:ESysColor, EAchorType, _MoveDirect_e - 使用E加大写枚举名前缀实现
* 强枚举类型:KSysColor, KMoveDirect, _DockType_k - 使用K大写枚举名前缀实现

类型别名:int32_t, imgIndex_t, fpos_t - 使用骆驼命名法加_t后缀实现

模板名: BinaryTreeT, Matrix44T - 使用后缀T表示模板类型

联合类型:UPropertyValue, _VoidPointer_u - 使用前缀U表示

内部(私有)或别名类型前面加_: _tchar, _sysinfo_st

公用成员函数: queryObjectList(const _tchar* pQueryStr) - 骆驼命名法表示函数
queryInfo(const wstr_t pMIName, ModuleInfo* _pMI);//输出变量在后加_p前缀,输入变量在加前p前缀

私有保护成员函数: get_function_type(void* p_val) - 使用小写下划线表示(私有函数形参前缀用p_或o_)

私有保护成员变量: m_pos, m_text, m_anchor_type - 使用前缀m_加小写下划线表示

公用成员变量: PosX, PosY, Text - 直接大写表示,但尽量不出现公用成员变量,而是封装

私有变量封装: _PosX, _PosY, _Text - 前缀_加大写表示,前缀_表示私有或保护,大写首字母提醒此变量是一个属性

函数形参变量: p_val, _p_result, pObjList, _pOutStr - 使用前缀p_加骆驼命名表示形参

普通变量: bRet, lsObject, entityTest - 骆驼[+匈牙利]命名法表示普通变量,其小写前缀为复杂对象类型[简单如int等可无视]

指针变量: _pOutStr表示堆变量, object_或object_p表示仅仅指向地址的指针(仅使用,不对内存操作)

getter/setter方法[函数]:Object* PosX(const int32_t p_x){} int32_t PosX(void) const{}
* 不能修改变量,需加const修饰符,如遇void* 则getter前后const如下 const _tchar* Str(void) const{}
* 不用getPosX或setPosX设置, 而是PosX()重载getter/setter实现。注意getter/setter类的函数,首字母必须大写
* setter其返回值为Object*,即return this,以实现链式设置
* 注意所有无参函数,形参表必须写void类型明确表示[重载]类型为void

宏定义或替换:_DEBUG, _OUTPRT, BUFFER_SIZE, DIRECT_RIGHT - 对于宏替换前缀用下划加大写,对于宏定义[类似常量]不加前缀下划直接大写

枚举常量: SC_RED, AT_BOTTOM, MD_UP - 枚举类型名简写加具体内容大写表示

普通常量: c_Filename, c_Default_option, c_Moveup - 使用c_前缀加首字母大写余全小写实现,例:for(int32_t i =0; i < c_Maxlength; i++){}, int a = c_Pi;

静态变量或全局函数: g_HTextureMgr, s_WndInfo, ms_Keys, cs_Webcfgpath 或 g_MixMatrix(), s_DfcgFrmProc(), ms_SetNULL(), _Test()
* 全局意义用g_或s_,每音节首字母大写,可与m_等修饰符共用[遇宏修饰或常量修饰,首字母必须大写],尽量少用静态或全局以降低耦合

常用变量前缀:bRet[Bool], arrTest[Array], lsObject[stl::list], hFile[Handle], fStream[FILE], _entity[*], szCaption[String of Zero]

宏检查语句:UI_FRAME_H_INCLUDED, _UI_FRAME_H_

命名空间:string_tools, debug_tools - 小写加下划线

二、物理架构

simple_prj 下面有 bin, obj, lib, design, tools, src, res, test八个主要目录

其中bin 与 obj存放编译中间文件及二进制代码结果
lib下有项目引用到的库文件及子目录\inc存放其库文件头文件
design 与 tools有项目的期望功能、项目的依赖关系说明文件、进度及感悟、示例代码及相关工具
src下为项目的主要代码
res为项目所用到的资源文件,包括图片、声音、字体等
test为项目所单独用到的测试项目,由若干测试子项目组成
* 未来如项目生成为运行库文件或提供给其他人使用时,会增加一个inc目录,该目录提供了运行库的头文件支持

项目的文件后缀名

main.h - 项目入口处声明的头文件,主要用于包含其他头文件,声明类型,声明函数或导出全局变量,描述入口文档及时间等
main.cc - 项目入口处代码
timer.t.cc - 测试用例文件,不包含在主项目中
connection.i.h - 数据库连接抽象接口的头文件
ui_button.h ui_button.cc uie_event.h cn_font_mgr.h - 普通项目文件,用[有时简化]小写兼下划表示
* 所有c++代码文件以.cc\.cpp或.h表示,模板文件用.hpp表示[增强编译识别],编译器大略使用GCC进行编译,中间静态库文件为.a

项目用名的后缀

foundation 基础文件夹,包含公用的类,基于本项目不可通用,对特定库较为依赖

module_ref.h 包含对该模块的基础依赖关系
module_base.h 包含对该模块的项目依赖关系及常见的宏定义,亦可简化替换成module.h
module_def.h 包含对该模块的基础类型别名、结构体定义等[通常定义在一个命名空间中]
* module.h 可引申为头文件为其他项目调用,通常用于导出到inc文件夹作第三方用

utility 功能文件夹,包含常见工具或功能,通常可以在其他项目中使用,对特定库不依赖

string_tools.h debug_tools.h 工具类[通常表示为某个静态单例类]
singleton.hpp 模板功能类

app 框架类文件夹,包含常用的自定义类库[也可包含第三方库],以编译形式共享
biz  业务逻辑文件夹,包含所有项目特有的业务逻辑或功能
view 视图文件夹,包含项目中该平台上特有的显示代码,无法独立出项目及库

关于工程路径及自定义[库]路径的约定

在项目中独有的不期望在其他项目中使用,则用工程路径
#include "src/view/main_frm.h"
#include "src/view/dkcp_frm.h"

在自定义[库]或期望共用的代码中则用相对路径以增强独立性
#include ".\frame\win32\appframe.h"
#include "..\foundation\app_base.h"

* 工程路径不使用"./??",相对路径必须使用.和..
* 工程路径需设置头文件目录下添项目路径
* CodeBlocks环境下添加库文件
    添加头文件:依次点击project->bulid options->Search directories,在该标签页中点击Compiler,单击Add按钮添加头文件路径
    添加静态库路径:依次点击project->bulid options->Linker setting,在该标签页中点击Add按钮添加静态库路径。

三、关于C++的补充说明

1.使用标准C库时,使用C++重载版本库,如
#include <string.h> 替换为 #include <cstring>
#include <stdio.h> 替换为 #include <cstdio>
同时使用strcat等标准库的函数时,应用std::strcat而不是直接strcat

2.弃用using namespace std;
改用 using std::strcat; 在某一段落里声明,减少命名空间混乱,减少编译查找时间

3.关于程序中的基本类型,程序中自定义库及业务逻辑部份只使用如下类型:
允许使用bool型,尽量不用unsigned标识符,用也尽量不作有符号数无符号数转换
使用int8_t定义小数值范围的int类型
使用int32_t明确定义32位int
使用int64_t替换long类型,其值加L
使用double明确替代float单浮点类型,其值加F或D
* 对于基础部份[编译器优化、较小值、标准库或过于基础内容]仍可以用int, float, long及unsigned,但保证其值范围不可过大
使用wchar_t*型数组和const char*(字符串常量指针)作较为基础核心的类型
使用FILE指针操作文件,弃用stream流及重载
使用std标准库std::string, std::vector, std::set, std::stack等类型作为基础类型进行开发。

4.关于扩展库
使用宏统一平台,如direct.h、io.h 或 sys/fcntl.h可用宏简单统一成_create之类的命名空间和函数
使用标准socket操作网络,不用winsock函数等特定类库,不得以不请先用宏或工厂类封装
特定库如glfw引用的基础类型如GLFLOAT则使用其基础类型,不使用标准类型。但封装后一定传入的是标准类型。
尽量使用POSIX类的标准C++特性和最新的稳定版本的开源类库及开发工具
简单功能可以使用自写代码完成基本功能需求即可,尽量减少库依赖

5.关于const限定词和char*的使用详解

a. 凡是用到""符号一律视为字符串常量,其特点是无法修改字符串值内容
b. 定义字符串常量必须const char* x = "abc"; 字符串abc视为字符常量数组,x储存内容为该数组的首地址。此数组内容不可变更,如x[0]='k'非法
c. const char *x; 指针可指向新的内容,但指向的内容无法修改。在C++中重载时与char*视为不同类型。比如:
x = new char[5];可以,但x[0]='c';非法。
char *b; x=b;可以,但strcpy(a,"xyz");非法
d. char* const y; 指针不可指向其他地址,但指向的内容可以修改。比如:
char* const y = new char[10];首次可以,再次y = new char[10]非法
char* const y; y = new char[10];非法,const必须赋初值!非法,无法修改指针 - const char*无此限制
!!!Warning: 允许y[0]='a';允许delete,但禁止y = NULL
e. const char* const z; 标识此字符串常量为真正的常量,与char* const z = "content";等同

f. 成员函数尾部出现const,表示此成员函数不能改变类成员变量的值,常用做getter
g. 引用的实质是指针,传递参数时,const &实质是* const指针,&&(左值引用)相当于const *

6.关于预编译头文件及调试、发布版本说明

1.请在stdafx.h或其他预编译头文件外创建相应.cpp文件,此文件仅包含一句#include "stdafx.h"。此外请在项目属性设置中设置预编译选项为"使用",而stdafx.h(或其他预编译文件)中设置其预编译选项为"创建"。这样重新构建时将自动重新生成.pch预编译文件。
2.在准备发布程序运行版本时,一定要初始化所有变量的初始值为0。调试版本运行时,编译器自动将变量值初始化为ccc,因此发布版本运行时可能导致未知的内存错误。发布运行版本将不启用assert宏,因此需要仔细检查每个函数体的入口值是否合法(必要时)和断言不启用时是否影响程序逻辑。

7. 使用C++0x特性应用到项目中,含nullptr(显式定义指针为空), auto(自动推导数据类型), decltype(从变量或表达式获取类型), override(显式声明派生类重写基类虚函数), final(显式声明此虚函数不可被派生类重写), 右键引用和强枚举类型。语法如下:
int *var=nullptr;
decltype(var) var2 = var;
auto vec = sample.getVector();
class A {
     virtual void a() const final; // do not override
     virtual void b();
     virtual void c();
     virtual void d() const;
     void k();           // not virtual
 };
class B : A {
     void a() const; // error: D::f attempts to override final A::a
     void b();       // OK
     void c() override;  // OK: overrides A::c()
     void d() override;  // error: wrong type
     void k() override;  // error: A::k() is not virtual
 };
Object&& object;
enum class KEnum1{ VAR1, VAR2 };
enum KEnum2 : unsigned int { VAR1, VAR2 };

8. 关于命名空间及枚举常量
应有项目自己的命名空间,枚举和常量定义必须在类定义里面定义。调用时应加类名前缀,如:
class UIBase {
   public:
      enum { c_Margin = 40, c_Space = c_Margin + 30 };
      enum EBaseDirection : int { UID_UP = 0, UID_DOWN, UID_LEFT, UID_RIGHT, c_Direction_number };
}; //class UIBase
调用时写成:
size_t set_position(UIBase::EBaseDirection pDirection, size_t x, size_t y) {
   if(pDirection == UIBase::UID_UP) return UIBase::c_Space;
}//function set_position
这样写便于记忆,不担心重定义,结构清晰,类自上而下分别写作公共(先写枚举常量及定义,后写公共函数和变量)、保护和私有。

附codeblocks默认代码 及代码缩写词 定义

 

///H

/***
 * Filename: $(ACTIVE_EDITOR_STEM).$(ACTIVE_EDITOR_EXT)
 * Author: ${#default.author}
 * Create: $(TODAY)
 * Summary: 
 */
 
 namespace ${#default.namespace} {
	 
 }//namespace ${#default.namespace}

/CPP
 
//! create by ${#default.author} @ $(TODAY)
#include "$(ACTIVE_EDITOR_STEM).h"

namespace ${#default.namespace} {

	

}//namespace ${#default.namespace}

/Class///
	
//!class $(Class name). |
class $(Class name){
public:
	$(Class name)();
	~$(Class name)();
protected:
private:
};// class $(Class name)

//!function construction.
$(Class name)::$(Class name)() {}

//!function destruction.
$(Class name)::~$(Class name)() {}
	

//Struct///

struct ${Struct name} {
	|
};//struct $(Struct name)

//fn

/*@time: $NOW
 *@author: ${#default.author}
 *@params: $(Parameter List)
 *@return($(Return Type)):
 */
$(Return Type) $(Class Name)::$(Function Name)($(Parameter List));

//!function $(Function Name). |
$(Return Type) $(Class Name)::$(Function Name)($(Parameter List)) {
}//Function $(Function Name)

npfn
/*@time: $NOW
 *@author: ${#default.author}
 *@return($(Return Type)):
 */
$(Return Type) $(Class Name)::$(Function Name)(); //!function $(Function Name).
|$(Return Type) $(Class Name)::$(Function Name)() {
}//End Function $(Function Name)

gsfn///
$(Property Type) _$(Property Name);//!Property $(Property Name). |

//!function getter/setter for $(Property Name)
inline $(Property Type) $(Property Name)() const { return _$(Property Name); }
inline void $(Property Name)(const $(Property Type) p$(Property Name)) { _$(Property Name) = p$(Property Name); }

另附上一个非常好的C++跨平台开发的建议 https://blog.csdn.net/fengbingchun/article/details/44005041

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值