当前位置: 首页 > news >正文

C++教程(五):C++高手养成之代码规范,如何写出规范优雅的程序

C++代码规范旨在提高代码的可读性、可维护性和一致性,同时减少潜在的错误和代码异常。以下是一些常见的C++代码规范。

1. 命名规范

1. 变量命名
局部变量和函数参数应采用小写字母开头的驼峰命名法(lowerCamelCase),即首字母小写,后续单词首字母大写。类的成员变量也采用 lowerCamelCase 命名,但要在尾部添加下划线 _ 以区别于局部变量和参数。全局变量不推荐使用,若必须使用,需置于命名空间内,并采用全小写字母加下划线分隔的命名方式。静态变量的命名规则与全局变量类似,也采用 lower_snake_case。

2. 常量命名
常量(包括常量表达式和常量变量)的命名应以大写字母 K 开头,并使用 UpperCamelCase 命名法。这样做是为了确保常量易于识别,同时与其他变量区分开。

3. 函数命名
函数名采用 lowerCamelCase 命名法,首字母小写,后续单词首字母大写。函数名称应能清楚描述其功能,通常为动词或动词短语。

4. 类型命名
类、结构体和枚举的名称应使用 UpperCamelCase,即每个单词首字母大写,单词连写。枚举值则采用 kUpperCamelCase 命名风格,与常量的命名方式相同,以便区分枚举值和其他变量。

5. 命名空间
命名空间名应全部小写字母,单词之间用下划线分隔。命名空间的作用是组织代码,避免全局命名冲突,尤其在大型项目中,合理的命名空间设计能够显著提升代码的组织性和可维护性。

6. 宏命名
宏定义(通过 #define 定义的预处理器指令)应使用全大写字母,单词之间用下划线分隔。宏在 C++ 中应尽量避免使用,除非在不得已的场景下才使用。

7. 文件命名
文件名应使用全小写字母,单词之间用下划线分隔。头文件的扩展名为 .h,实现文件的扩展名为 .cc。测试文件的命名规则是将被测试文件的名称加上 _test 后缀,以明确其测试属性。

8. 测试函数
在 Google Test 框架中,测试函数命名通常以 UpperCamelCase 风格,且应清晰描述测试的功能。函数名通常为 TEST 宏定义的类中的方法,用来确保代码的正确性。

9. 命名冲突处理
通过命名空间可以有效避免全局命名冲突。所有代码应当放在命名空间内,尤其在大型项目中,合理的命名空间管理不仅避免冲突,还能提升代码组织性。

10. 函数模板和类模板
模板函数和模板类的命名遵循普通函数和类的命名规则,模板参数通常使用大写字母,如 T、U 等。这样可以提高模板的可读性和一致性。

11. 访问控制和成员函数
类的访问控制符应按 public、protected、private 的顺序出现,以确保访问权限划分清晰。类的私有成员变量和私有函数应遵循 lowerCamelCase 命名法,并以下划线 _ 结尾。

12. 缩写和首字母缩写
命名中应避免使用不常见的缩写,确保代码的易读性。常见的缩写(如 HTML、URL 等)可以大写使用,但在驼峰命名中,只有首单词为缩写时,才应全部大写,否则只需首字母大写。

13. 私有类成员和私有函数
类的私有成员变量和私有函数采用 lowerCamelCase 命名法,并在末尾添加下划线 _。这有助于区分私有成员和其他类型的成员,增强代码的清晰度。

// 头文件和实现文件命名
// 文件:my_class.h
// 文件:my_class.ccnamespace my_project {class MyClass {public:void setValue(int value);int getValue() const;private:int value_;void privateFunction_();
};}  // namespace my_project// 常量定义
const int kMaxValue = 100;
const double kPi = 3.14159;// 函数定义
void MyClass::setValue(int value) {value_ = value;
}int MyClass::getValue() const {return value_;
}// 测试文件:my_class_test.cc
#include "my_class.h"
#include <gtest/gtest.h>TEST(MyClassTest, HandlesDefaultInput) {MyClass my_class;my_class.setValue(10);EXPECT_EQ(my_class.getValue(), 10);
}TEST(MyClassTest, HandlesEdgeCase) {MyClass my_class;my_class.setValue(100);EXPECT_EQ(my_class.getValue(), 100);
}

2. 注释规范

注释应简洁明了,解释“为什么”而不是“是什么”。
单行注释使用//,多行注释使用/* ... */。
为函数和类添加详细注释,说明其功能、参数和返回值。
对复杂逻辑的代码段进行详细注释。
使用TODO标记未完成的工作,并添加责任人。
头文件应包含文件作用的说明注释。

// car.h
// 该文件定义了Car类及其相关的函数和属性。/** Car类表示一辆汽车,包含速度和燃料信息。* 它支持更新速度的功能。*/
class Car {
public:// 更新汽车速度// @param new_speed: 新的速度值void updateSpeed(int new_speed);private:int speed_;  // 当前速度float fuel_level_;  // 当前燃料水平
};// 计算两个整数的和
// @param a: 第一个整数
// @param b: 第二个整数
// @return: 两个整数的和
int add(int a, int b);// TODO(john_doe): 优化此函数以提高性能
void inefficientFunction() {// 目前的实现很慢
}

3. 格式规范

1. 缩进和空格
Google C++ 代码使用 2 个空格进行缩进,而不是使用 Tab 键,以确保在不同编辑器和环境下代码对齐一致。运算符和关键字之间应留空格,例如在赋值、比较和算术运算符的两侧都应加空格。函数调用和参数之间不应有空格,参数之间则用逗号和空格分隔。

2. 行长度
每行代码的长度应不超过 80 个字符。如果代码行超过 80 个字符,应进行适当的折行,通常是在逻辑运算符或逗号后换行,后续行相对于上一行多缩进 4 个空格。

3. 括号与换行
左大括号应紧随声明或关键字,不应独占一行。右大括号应独立成行。对于单行的控制结构语句,虽然可以省略大括号,但为减少错误风险,建议始终加上大括号。函数定义或声明后的代码块应换行,函数体内的代码应与大括号对齐。每个语句应独立成行,不允许将多个语句写在同一行。

4. 空行
空行用于分隔代码的不同逻辑部分。在不同函数或逻辑块之间,以及函数实现之间,都应留空行,以提高代码的可读性。

5. 头文件顺序
头文件的引入顺序应依次为:C++ 标准库头文件,第三方库的头文件,最后是项目的头文件。不同部分之间用空行隔开。头文件应使用 #pragma once,或传统的 include guard 以防止重复包含。

6. 指针和引用
声明指针和引用时,符号 * 和 & 应紧靠变量名,而不是类型名,以确保一致的代码风格。

#include <iostream>// 计算两个数的和。
// @param a 第一个整数。
// @param b 第二个整数。
// @return 两数之和。
int AddNumbers(int a, int b) {return a + b;
}int main() {int result = AddNumbers(5, 3);  // 计算 5 + 3std::cout << "Result: " << result << std::endl;return 0;
}

4. 头文件规范

头文件保护:使用 #pragma once 或者 #ifndef/#define 进行头文件保护,防止重复包含。

头文件和源文件分离:类声明放在头文件 (.h 或 .hpp) 中,类的实现放在源文件 (.cpp) 中。

#pragma once#ifndef MYCLASS_H
#define MYCLASS_Hclass MyClass {// 类定义
};#endif  // MYCLASS_H

5. 智能指针

避免直接使用裸指针,优先使用 std::unique_ptr 和 std::shared_ptr 来管理资源,防止内存泄漏。

std::unique_ptr<Car> car = std::make_unique<Car>();

6. 异常处理

使用 try-catch 处理异常,而不是通过返回错误码。
不要捕获所有异常(如 catch (...)),应捕获特定类型的异常。

try {// 可能抛出异常的代码
} catch (const std::exception& e) {std::cerr << e.what();
}

7. 现代C++特性

充分利用现代C++特性(如auto、lambda表达式、nullptr等)提高代码的简洁性和安全性。

auto it = myVector.begin();

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C# Action和delegate区别及示例代码
  • tb的数数问题(牛客小白月赛)
  • Vue3新组件transition(动画过渡)
  • ubuntu18.04升级到20.04
  • 【JavaScript】LeetCode:41-45
  • Python 低层多线程接口_thread的用法
  • Unity UGUI的核心渲染组件
  • Linux 内存管理机制概述
  • 整合多方大佬博客以及视频 一文读懂 servlet
  • 数值计算 --- 平方根倒数快速算法(中)
  • 邮件安全治理
  • CVE-2024-2389 未经身份验证的命令注入
  • (PySpark)RDD实验实战——取一个数组的中间值
  • 树和二叉树的概念以及结构
  • Flink难点和高阶面试题:Flink的状态管理机制如何保证数据处理的准确性和完整性
  • 11111111
  • 3.7、@ResponseBody 和 @RestController
  • Angular Elements 及其运作原理
  • bearychat的java client
  • java8 Stream Pipelines 浅析
  • java8-模拟hadoop
  • javascript面向对象之创建对象
  • Java小白进阶笔记(3)-初级面向对象
  • JSONP原理
  • Python实现BT种子转化为磁力链接【实战】
  • React-flux杂记
  • Twitter赢在开放,三年创造奇迹
  • Vue.js-Day01
  • Vue小说阅读器(仿追书神器)
  • Webpack 4x 之路 ( 四 )
  • 反思总结然后整装待发
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 使用权重正则化较少模型过拟合
  • 鱼骨图 - 如何绘制?
  • 阿里云ACE认证之理解CDN技术
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #大学#套接字
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (~_~)
  • (0)Nginx 功能特性
  • (1) caustics\
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (9)YOLO-Pose:使用对象关键点相似性损失增强多人姿态估计的增强版YOLO
  • (a /b)*c的值
  • (Charles)如何抓取手机http的报文
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (推荐)叮当——中文语音对话机器人
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)基于IDEA的JAVA基础10
  • (转)Sublime Text3配置Lua运行环境
  • (转)Unity3DUnity3D在android下调试