C++代码规范

一、命名规范

对于C++代码,每个人的风格和习惯各不尽相同,但是为了在项目中形成一个统一的,阅读性比较好的代码,这里参考了主要的开源代码、国内外各大厂以及以往的项目经验,这里对C++代码的命名进行了一个约定规范。

1、目录/文件

规范:使用小写字母数字下划线,多个单词间用下划线分隔。
原因:Windows对目录和文件是大小写不区分的,而Linux是大小写区分的。为了达到平台统一,这里规定都使用小写字母。
示例:

目录:app_cxx/proc_ui/src/firewall
文件:firewall_mgr.h、main.cpp、nfsv2.cpp

2、函数/接口

规范:使用小驼峰命名法
原因:大部分著名的开源项目以及大厂对外提供的API都是这样的命名规范。
示例:

int test()
{
    return 0;
}

int getLocalPort()
{
    return 4335;
}

3、命名空间

规范:使用小写字母数字下划线,多个单词间用下划线分隔 (尽量只使用一个单词)
原因:
示例:

namespace logger
{
}

4、结构体/类

规范:使用大驼峰命名法不包含下划线
原因:
示例:

struct SendData
{
};

class LoggerManager
{
};

5、变量

规范:使用小驼峰命名法

(1)局部变量

示例:

void test()
{
    int reqNum = 0;
}

(2)全局变量

补充:需要加前缀g_
示例:

int g_reqNum= 0;

(3)静态变量

补充:需要加前缀s_
示例:

void test()
{
    static int s_reqNum = 0;
}

补充:当它同时也是全变量时使用全局变量的命名方式
示例:

int g_reqNum = 0;

(4)类成员变量

补充:需要加前缀m_
示例:

class ServerInfo
{
private:
    int m_reqNum
}

(5)类静态变量

补充:需要加前缀s_
示例:

class ServerInfo
{
private:
    static int s_reqNum;
}

(6)常量

补充:需要大写字母
原因:
示例:

const int MAX_NUM = 1024;

5、宏定义

规范:需要大写字母
原因:
示例:

#define CACHE_PATH "/data/cache"

6、枚举

规范:枚举名使用大驼峰命名法,枚举名建议带上class类型,枚举值需要小写字母
原因:避免和宏定义冲突
示例:

enum class ResultType
{
    ok,
    open_fail,
    unknown
};

二、注释规范

规范:尽量用/* */进行注释,避免使用//。
原因:使用//时,当不小心把其下面的一行代码回退到//所在行时,如果没注意的话容易造成逻辑出错。

1、结构体/类注释

示例:

/**
 * @brief 用户信息集合
 */
struct UserInfo
{
};

2、接口注释

示例:

/**
 * @brief 查询用户信息
 * @param username 用户名
 * @return 用户信息
 */
UserInfo queryUserInfo(const std::string& username);

3、变量注释

示例:

int age = 0; /* 年龄 */

三、设计规范

1、声明/定义的位置?

规范:宏/枚举/变量/接口的声明和定义需要就近原则,能不跨文件就不跨文件。
原因:使得代码更加内聚,提升代码阅读的便利性。
示例:
在类DbMgr中使用了宏定义:#define QUEYR_OK 1

  • 如果该宏只在源文件DbMgr.cpp中使用,则宏定义放在DbMgr.cpp中。
  • 如果该宏仅仅作为返回值透露到外部模块,则宏定义放在DbMgr.h中。
  • 如果该宏在其他若干业务中频繁使用,则宏定义放在公共的业务枚举定义文件中(可能如:enum_def.h)。

2、结构体(struct) or 类(class)?

规范:当定义的类型只是数据的集合且内部无复杂的处理逻辑时选择用struct,反之如果更注重行为的封装则选择class
原因:struct存在于栈上,用完即销毁。 注意: 由于栈有容量限制,避免在struct中存放超大量的值类型。
示例:

struct UserInfo
{
    UserInfo() : age(0), sex(0) {}
 
    std::string username;
    int age;
    int sex;
};
class Grade
{
public:
    std::vector<UserInfo> queryUserInfoList(const std::string& username);
};

3、单文件(.hpp) or 多文件(.h,.cpp) ?

规范:当模块只是一些信息的集合且无复杂内部逻辑可以使用.hpp,反之使用多文件方式。
原因:模块逻辑复杂时,会经常变动,如果引用的外部模块多而使用.hpp时,编译时间会变长。
示例:
单文件user_info.hpp

#pragma once
#include <string>
 
struct UserInfo
{
    UserInfo() : age(0), sex(0) {}
 
    std::string username;
    int age;
    int sex;
};

多文件grade.hgrade.cpp

#pragma once
#include "user_info.h"
 
class Grade
{
public:
    std::vector<UserInfo> queryUserInfoList(const std::string& username);
};
#include "grade.h"
 
std::vector<UserInfo> Grade::queryUserInfoList(const std::string& username)
{
    return std::vector<UserInfo>{};
}

4、单例类

规范:把构造函数声明为私有。
原因:基于单例的定义,不允许类型不受控制的实例化。
示例:
头文件DbMgr.h

#pragma once
 
class DbMgr
{
private:
    DbMgr();
 
public:
    static DbMgr& getInstance();
};

源文件DbMgr.cpp

DbMgr::DbMgr() {}
 
DbMgr& DbMgr::getInstance()
{
    static DbMgr s_instance;
    return s_instance;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值