Coding Style
File Organization
标准 C++ 项目布局:
project/
├── include/
│ └── project/
│ └── header.h
├── src/
│ └── source.cpp
├── tests/
│ └── test_source.cpp
└── CMakeLists.txt or project.pro
include/— 公共头文件src/— 实现文件tests/— 测试文件
Include Guards
始终使用 #ifndef/#define/#endif,不要用 #pragma once。
格式:
#ifndef PROJECTNAME_MODULENAME_CLASSNAME_H_
#define PROJECTNAME_MODULENAME_CLASSNAME_H_
// ...
#endif // PROJECTNAME_MODULENAME_CLASSNAME_H_
Include Order(在 .cpp 中)
#include "OwnHeader.h" // 1. 自己的头文件
#include "ProjectHeader1.h" // 2. 项目内部头文件
#include "ProjectHeader2.h"
#include <QWidget> // 3. Qt / 第三方头文件
#include <QPainter>
Naming Conventions
| 类别 | 风格 | 示例 |
|---|---|---|
| 类 | PascalCase | Window, TcpClient, MetaType |
| 公共方法 | camelCase | moveToCenter(), getThemeMode() |
| 私有方法 | _ + camelCase |
_addChildItem(), _initWindow() |
| 成员变量 | _ + camelCase |
_mapCanvas, _isLeftButtonDown |
| 信号 | camelCase | themeModeChanged() |
| 槽 | on + Source + Event |
onMinButtonClicked() |
| 枚举值 | PascalCase | Light = 0x0000, Dark = 0x0001 |
| 枚举容器 | PascalCase + Type 后缀 |
ApplicationType::WindowDisplayMode |
控件命名
控件变量使用"业务含义 + 组件类型"命名,末尾体现组件类型:
- 好:
_unitComboBox,_minimumEdit,_applyPushButton - 不好:
_unit,_minimum
View 成员同时说明业务用途与实际类型,如 _parameterTableView、_formulaTreeView。
Model 成员按业务职责命名,如 _parameterInstantiationModel、_formulaOptionModel。
布局变量命名为 mainLayout,子布局按职责命名并以 Layout 结尾,如 buttonLayout。
QString 字面量
不要使用 QStringLiteral:
QString text = "普通字符串"; // 好
QString text = QStringLiteral("普通字符串"); // 不好
text += QString("格式:%1").arg(value); // 好
Class Structure
类结构
公共头文件:
class ClassNamePrivate;
class ClassName : public BaseClass
{
Q_OBJECT
public:
explicit ClassName(QObject* parent = nullptr);
~ClassName() override;
void methodName();
int getValue() const;
signals:
void valueChanged();
private:
std::unique_ptr<ClassNamePrivate> d;
};
私有头文件(private/ClassNamePrivate.h):
class ClassName;
class ClassNamePrivate : public QObject
{
Q_OBJECT
public:
explicit ClassNamePrivate(ClassName* q);
~ClassNamePrivate() = default;
void init();
void onSomeEvent();
ClassName* q;
int someValue{0};
};
Constructor pattern
ClassName::ClassName(QObject* parent)
: BaseClass(parent), d(std::make_unique<ClassNamePrivate>(this))
{
d->init();
}
Enum 定义
每个库在 Def.h 中定义自己的枚举。
enum class ApplicationType
{
Normal = 0x0000,
ElaMica = 0x0001,
};
枚举值可以是十六进制,可以为负。容器类命名:PascalCase + Type。
Memory Management
- PIMPL d-pointer:
std::unique_ptr<XxxPrivate> - Qt widgets:使用原始指针配合 parent-child 所有权
- 始终初始化指针为
{nullptr},bool 为{false},int 为{0} - 不要用
std::make_unique/std::make_shared管理 Qt 拥有的对象 - QObject 延迟删除使用
deleteLater()
Casting
仅使用 C++ 风格的类型转换:static_cast<T>(val), dynamic_cast<T*>(ptr), reinterpret_cast<T>(ptr)。禁止 C 风格转换。
Formatting
- 单行
if、else、for、while也必须使用大括号 switch中的case、default分支体必须显式添加大括号- 函数定义必须展开,函数签名和大括号分别换行
- 使用项目根目录的
.clang-format进行格式化(LLVM-based, 4-space indent, Allman braces)
Comments
-
代码标识符(类名、方法名、变量名):英文
-
文档注释和用户可见信息:中文
-
不要写解释代码做什么的注释 — 起好名字就够了。只在 WHY 不明显时才加注释(隐藏的约束、微妙的不变量、变通方案)
-
内部结构体的每个字段必须有注释,说明数据身份、业务含义或有效条件
最后更新时间:2026-10-18 16:13
评论(0) 最新 热门
登录 后才能评论。