# 代码质量标准知识体系 ## 编码规范标准 ### Qt Coding Style ```cpp // 类名使用帕斯卡命名法 class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void onButtonClicked(); // 槽函数使用on前缀 private: Ui::MainWindow *ui; // 成员变量使用驼峰命名 QTimer *m_timer; // 私有成员使用m_前缀 }; ``` ### Google C++ Style Guide要点 - **命名约定**:类名PascalCase,函数名camelCase,常量UPPER_CASE - **文件组织**:头文件包含顺序,前向声明的使用 - **代码格式**:缩进、空格、换行的统一标准 - **注释规范**:文档注释和行内注释的写法 ### 现代C++最佳实践 ```cpp // 使用auto进行类型推导 auto widget = std::make_unique(); // 使用范围for循环 for (const auto& item : container) { // 处理item } // 使用初始化列表 class MyClass { public: MyClass(int value) : m_value{value} {} // 统一初始化语法 private: int m_value; }; ``` ## 代码质量度量 ### 复杂度指标 - **圈复杂度**:衡量代码逻辑复杂性,建议≤10 - **认知复杂度**:衡量代码理解难度,建议≤15 - **嵌套深度**:控制结构嵌套层数,建议≤4 - **函数长度**:单个函数行数,建议≤50行 ### 重复代码检测 ```cpp // 避免代码重复,提取公共函数 void setupButton(QPushButton* button, const QString& text, const QString& iconPath) { button->setText(text); button->setIcon(QIcon(iconPath)); button->setStyleSheet("QPushButton { padding: 8px; }"); } ``` ### 耦合度分析 - **传入耦合(Ca)**:依赖此模块的其他模块数量 - **传出耦合(Ce)**:此模块依赖的其他模块数量 - **不稳定性(I)**:I = Ce / (Ca + Ce),值越小越稳定 - **抽象度(A)**:抽象类占总类数的比例 ## 设计质量原则 ### SOLID原则 ```cpp // 单一职责原则 (SRP) class FileReader { public: QString readFile(const QString& filename); }; class FileWriter { public: bool writeFile(const QString& filename, const QString& content); }; // 开闭原则 (OCP) class Shape { public: virtual double area() const = 0; virtual ~Shape() = default; }; class Rectangle : public Shape { public: Rectangle(double width, double height) : m_width(width), m_height(height) {} double area() const override { return m_width * m_height; } private: double m_width, m_height; }; // 里氏替换原则 (LSP) // 子类对象应该能够替换父类对象而不影响程序正确性 // 接口隔离原则 (ISP) class Readable { public: virtual QString read() = 0; virtual ~Readable() = default; }; class Writable { public: virtual bool write(const QString& data) = 0; virtual ~Writable() = default; }; // 依赖倒置原则 (DIP) class DataProcessor { public: DataProcessor(std::unique_ptr reader) : m_reader(std::move(reader)) {} void process() { QString data = m_reader->read(); // 处理数据 } private: std::unique_ptr m_reader; }; ``` ### DRY原则 (Don't Repeat Yourself) ```cpp // 避免重复代码,使用模板或函数 template void connectSignalSlot(T* sender, void(T::*signal)(), QObject* receiver, void(QObject::*slot)()) { QObject::connect(sender, signal, receiver, slot); } ``` ### KISS原则 (Keep It Simple, Stupid) ```cpp // 简单直接的实现 bool isValidEmail(const QString& email) { return email.contains('@') && email.contains('.'); } // 而不是复杂的正则表达式(除非确实需要) ``` ## 错误处理和异常安全 ### 异常安全等级 ```cpp // 基本保证:不会泄漏资源 class BasicSafety { public: void operation() { auto resource = std::make_unique(); // 即使抛出异常,resource也会自动释放 doSomething(); } }; // 强异常安全:操作要么成功,要么保持原状 class StrongSafety { public: void operation() { auto backup = m_data; // 备份当前状态 try { modifyData(); } catch (...) { m_data = backup; // 恢复原状 throw; } } private: Data m_data; }; // 无异常保证:操作绝不抛出异常 class NoThrow { public: void operation() noexcept { // 确保不会抛出异常的操作 } }; ``` ### Qt错误处理模式 ```cpp // 使用返回值表示错误状态 enum class FileError { Success, FileNotFound, PermissionDenied, InvalidFormat }; class FileManager { public: FileError loadFile(const QString& filename, QString& content) { QFile file(filename); if (!file.exists()) { return FileError::FileNotFound; } if (!file.open(QIODevice::ReadOnly)) { return FileError::PermissionDenied; } content = file.readAll(); return FileError::Success; } }; ``` ## 性能和内存管理 ### RAII (Resource Acquisition Is Initialization) ```cpp class DatabaseConnection { public: DatabaseConnection(const QString& connectionString) { m_db = QSqlDatabase::addDatabase("QSQLITE"); m_db.setDatabaseName(connectionString); if (!m_db.open()) { throw std::runtime_error("Failed to open database"); } } ~DatabaseConnection() { if (m_db.isOpen()) { m_db.close(); } } // 禁止拷贝 DatabaseConnection(const DatabaseConnection&) = delete; DatabaseConnection& operator=(const DatabaseConnection&) = delete; // 允许移动 DatabaseConnection(DatabaseConnection&&) = default; DatabaseConnection& operator=(DatabaseConnection&&) = default; private: QSqlDatabase m_db; }; ``` ### 智能指针使用指南 ```cpp // unique_ptr:独占所有权 std::unique_ptr createWidget() { return std::make_unique("Click me"); } // shared_ptr:共享所有权 std::shared_ptr getModel() { static auto model = std::make_shared(); return model; } // weak_ptr:避免循环引用 class Parent { public: void addChild(std::shared_ptr child) { m_children.push_back(child); child->setParent(shared_from_this()); } private: std::vector> m_children; }; class Child { public: void setParent(std::shared_ptr parent) { m_parent = parent; // 使用weak_ptr避免循环引用 } private: std::weak_ptr m_parent; }; ``` ## 测试和质量保证 ### 单元测试最佳实践 ```cpp class TestCalculator : public QObject { Q_OBJECT private slots: void testAddition_data(); void testAddition(); void testDivisionByZero(); private: Calculator m_calculator; }; void TestCalculator::testAddition_data() { QTest::addColumn("a"); QTest::addColumn("b"); QTest::addColumn("expected"); QTest::newRow("positive numbers") << 2 << 3 << 5; QTest::newRow("negative numbers") << -2 << -3 << -5; QTest::newRow("mixed numbers") << -2 << 3 << 1; } void TestCalculator::testAddition() { QFETCH(int, a); QFETCH(int, b); QFETCH(int, expected); QCOMPARE(m_calculator.add(a, b), expected); } ``` ### 代码审查检查清单 - **功能正确性**:代码是否实现了预期功能 - **边界条件**:是否处理了所有边界情况 - **错误处理**:是否有适当的错误处理机制 - **性能考虑**:是否存在性能瓶颈 - **内存安全**:是否存在内存泄漏或悬空指针 - **线程安全**:多线程环境下是否安全 - **可读性**:代码是否清晰易懂 - **可维护性**:代码是否便于后续维护