C++编程规范和编译过程详解
前言:因为c++基础打得不牢,所以准备花点时间再学一下c++的基础知识,主要是看网易云课堂里面的免费课程,把一些知识点做个笔记记下来。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1:编程规范
1 头文件
1.1 使用头文件保护
使用#define进行头文件保护,而不使用微软的#pragma once。
为了保证唯一性,头文件保护的命名需要基于项目代码路径,比如Project\Src\Area\File.h 则文件的保护应该像这样:
1 2 3 4 | #ifndefine PROJECT_SRC_AREA_FILE_H #define PROJECT_SRC_AREA_FILE_H … #endif |
1.2 头文件依赖
使用前置声明减少头文件的所要包含的文件数量,也就减少了需要重新编译文件的几率。
对于需要在头文件里使用其他文件中定义的类时,如果只是使用类的声明而不是具体定义,应该是用前置声明代替包含整个文件,如下:
使用class SomeClass;
不使用 #include “SomeClass”。
1.3 包含头文件的顺序
顺序如下:C库、C++库、其他库.h、项目内的.h,如果次文件是cpp文件,那么要首先包含其对应的头文件,然后再按前述顺序。每个层级用空行分隔,同一层级的文件顺序按英文字母先后顺序排列,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include“MyFile.h” (如果次文件是cpp文件,首先包含自己的头文件) #include<stdio.h> #include<unistd.h> #include<iostream> #include<map> #include<string> #include“lib/Alpha.h” #include“lib/Beta.h” #include“other/zoo.h” #include“bar.h” #include“foo.h” |
2 作用域
2.1 全局变量
尽量不要使用全局变量,根据经验,全局变量起的作用往往仅是一个静态变量。如果非要使用全局变量,考虑使用单例模式代替。
多线程中使用的全局变量,不要使用class类型(包括STL容器),避免class内部的实现非线程安全而导致bug。
3 类
3.1 声明顺序
成员先后顺序:typedef、enum、常量、构造析构函数、成员函数,成员变量。
域先后顺序:public、protected、private。
比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Class MyClass { public : public : voidFoo(); protected : voidBar(); private : voidFunc(); public : intm_nCommonVar; private : intm_nMyVar; }; |
3.2 构造函数
构造函数只负责简单的初始化功能,如果需要进行有意义的初始化,请使用Init()函数。
*严禁在构造函数中调用虚函数。
3.3 拷贝构造函数
仅需要拷贝一个对象时才定义拷贝构造函数,否则明确在private域中使用声明DISALLOW_COPY_AND_ASSIGN,避免编译器隐式声明的拷贝构造函数导致的不确定行为。如下:
1 2 | private : DISALLOW_COPY_AND_ASSIGN(MyClass); |
3.4 结构体和类
只有数据时,使用结构体,否则使用类。
3.5 继承
尽量使用组合代替继承。
如果类中有一个virtual函数,则析构函数必须声明为virtual。
所有继承必须为public,私有继承使用其它实现方式替代。
3.6 多重继承
尽量避免使用多重继承,除非是COM。
3.7 模板
尽量不要使用模板,确定使用模板时确保一年后回头你还能看懂你的代码,并且调试这段模板无压力。
3.8 操作符重载
尽量避免使用操作符重载。
4 其它特性
4.1 异常处理
不要使用异常处理。
4.2 RTTI(运行时类型识别)
不要使用RTTI,也就是dynamic_cast,非要使用只能说明设计有缺陷。
原因:dynamic_cast会失败,而且不安全,难维护。
4.3 前置自增和自减
不考虑结果使用的情况下,尽量使用++i代替i++,因为++i效率更高。
4.4 const使用
尽量使用const修饰变量。
5 注释
5.1 头文件注释
头文件开头部分必须使用注释,说明此文件的作者、作用等信息。
即可证明你有多叼,也可让后人叼你。
格式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | /************************************************************************ * * @description: XLBrowserAppSupport的Lua接口封装 * * @author: Gaoyunxiang * @date: 2015.11.10 * * @last modified author: * @last modified date: * * @ copyright Xunlei Network 2015 - * *************************************************************************/ |
5.2 类注释
声明类之前需要使用类注释,说明此类的使用用途及注意事项
如下:
1 2 3 4 | // 浏览器类。 // 实现浏览器的常用功能,如导航等。 // 需由浏览器工厂类来创建实例。 class Browser{}; |
5.3 函数注释
重要或难理解的函数,需要在函数声明前加上注释。
比如:
1 2 3 4 5 | // 做加法 // nVar1:第一个加数 // nVar2:第二个加数 // 返回值:相加结果 int Add( int nVar1, int nVar2); |
5.4 逻辑注释
对于很难理解、重要、实现精彩的部分必须加上注释。
5.5 TODO注释
对于那些来不及实现、暂未实现、需要去实现的地方加上TODO注释。
如下:
// TODO: Fly to the moon.
6 编码风格
6.1 命名规则
尽量不要使用缩写,严禁使用不明单词的缩写。
类名:大写字母开头,每个单词首字母大写。
函数名:大写字母开头,每个单词首字母大写
变量名:首字母(通常为前缀)小写,用下划线分割
6.2 变量前缀
前缀为小写,后面第一个字母为大写
前缀的结尾为_时(如m_..),后面第一个字母为小写
short/int/size_t..,加n,如int nVal =1;
long,加l
float/double..,加f
bool/BOOL..,加b
DWORD,加dw
char*,加sz,如char *szVal= “abc”;
wchar_t*,加wsz
string,加str
wstring,加wstr
指针,加p
long指针,加lp
函数指针,加pfunc
vector,加vec
list,加list
map,加map
句柄类,加h
类成员变量,加m_,如HWND m_hParentWnd= 0x66666666;
全局变量,加g_
静态变量,加s_
常量,全部字母大写
类名,加C
…
6.3 缩进和换行
使用空格代替table,在VS里将table设置成4个空格。每个级别进行4个空格的缩进。
不要连续使用多于一次的换行。
6.4 花括号
另起一行使用。
6.5 条件、循环、开关等语句
关键字后面加空格再使用。
比如:
If ();
while ();
switch语句后的case:部分加作用域{}。
7 其它注意事项
7.1 堆分配和释放
new/delete等堆操作,必须成对出现。
尽量遵从谁分配谁释放的原则。
7.2 引用计数
AddRef()/Release()必须成对出现。
尽量遵从谁分配谁释放的原则。
7.3 指针、句柄使用完释放后必须设置成NULL。
7.4 函数功能要单一,避免耦合多功能,严禁CreateAndNavigate这种函数。
7.5 指针的空值比较使用NULL,而不是0。
7.6 浮点数的零值比较严禁使用== 0。
7.7 避免直接使用微软二次定义的数据类型,比如DWORD,使用其原始的unsigned long,方便跨平台。
2:C++的编译和执行

流程图如下:
从.cpp文件到.exe文件可以用 g++ -o HelloWorld HelloWorld.cpp 一步到位生成HelloWorld.exe可执行文件。下面图是整个过程按照上图的拆分,了解一下即可。
3:课程作业
1 /* 2 * 文件名: Charpter2 3 * 描 述: 输出寒冰射手.艾希的详细信息 4 * 作 者:刘雷 5 * 时 间:2019/10/9 6 * 版 权:version 1.0 7 */ 8 #include <iostream> 9 10 using namespace std; 11 12 int main() 13 { 14 cout << "名称:寒冰射手.艾希" << endl; 15 cout << "伤害:56\t\t攻击距离:600" << endl; 16 cout << "护甲:15.5(+3.4)\t魔抗:30(+0.0)\n" 17 << "生命值:395(+79)\t生命回复:0.9(+0.11)\n" 18 << "法力值:280(+32)\t法力回复:1.26(+0.08)\n" 19 << "移速: 325\t\t" << "定位:ADC 辅助\n" 20 << "点券:450" << endl; 21 return 0; 22 }
作者:你的雷哥
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!