shiyb
2025-05-19 9ca199497985c526c31e8884f6911fd49be6b807
Merge branch 'master' of ssh://117.78.1.188:29418/test-upload
修改了错误示例
1个文件已删除
3个文件已修改
137 ■■■■■ 已修改文件
Test/Test.pro 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Test/errorexample.cpp 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Test/errorexample.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Test/linestyle.cpp 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Test/Test.pro
@@ -17,13 +17,11 @@
SOURCES += \
    errorexample.cpp \
    linestyle.cpp \
    main.cpp \
    mainwindow.cpp
HEADERS += \
    errorexample.h \
    linestyle.h \
    mainwindow.h
FORMS += \
Test/errorexample.cpp
@@ -1,11 +1,132 @@
#include "errorexample.h"
#include <QFile>
#include <QLabel>
#include <QPushButton>
errorexample::errorexample() {
  // 1.未包含必要的头文件
  // 错误:缺少 #include <QLabel>
  QLabel label("Hello");  // 编译错误:'QLabel' was not declared in this scope
  label.show();
  //-----------指针常见问题---------------
  //①空指针解引用
  QWidget *widget = nullptr;
  widget->show();  //对值为nullptr的指针进行访问操作,会引发崩溃
  //解决办法:
  QWidget *widget1 = nullptr;
  if (widget1) {  //使用指针前,先确认其是否为nullptr
    widget1->show();
  }
  //②野指针
  //指针所指向的内存已经被释放,但后续仍在使用该指针
  QWidget *widget2 = new QWidget;
  delete widget2;
  widget2->show();  //此时widget2已经变成野指针
  //解决办法:
  //对象释放之后,及时将指针置为nullptr(利用 Qt
  //对象的父子关系机制来自动管理内存)
  QWidget *widget3 = new QWidget;
  delete widget3;
  widget3 = nullptr;  //避免野指针
  //③内存泄露:未释放动态分配的内存
  void createLeak() {
    int *ptr = new int(10);  //分配后未释放
  }
  //解决办法:
  void createLeak() {
    int *ptr = new int(10);  //分配后未释放
    delete ptr;
    ptr = nullptr;
  }
  //④父子关系误用
  QWidget *parent = new QWidget;
  QPushButton *button = new QPushButton(parent);
  delete button;  // 手动删除子对象
  delete parent;  // 崩溃!父对象试图再次删除已释放的 button
  //解决办法:依赖对象树自动管理
  QWidget *parent2 = new QWidget;
  QPushButton *button2 = new QPushButton(parent);
  delete parent2;  // 自动删除所有子对象(包括 button)
  //⑤智能指针与对象树冲突
  //混合使用父对象和智能指针
  QWidget *parent3 = new QWidget;
  // 错误:父对象已管理 button,智能指针会导致双重释放
  std::unique_ptr<QPushButton> button3(new QPushButton(parent));
  //解决办法1:仅用父对象管理
  QWidget *parent4 = new QWidget;
  QPushButton *button4 = new QPushButton(parent4);  // 父对象负责释放
  //解决办法2:无父对象时使用智能指针
  std::unique_ptr<QPushButton> button5 = std::make_unique<QPushButton>();
  //⑥容器中的指针管理
  // 忘记释放files数组及其中的指针所指向的内存
  QFile *files = new QFile[10];
  for (int i = 0; i < 10; ++i) {
    files[i].setFileName("file" + QString::number(i));
  }
  //解决办法:
  QFile **files1 = new QFile *[10];
  for (int i = 0; i < 10; ++i) {
    files[i].setFileName("file" + QString::number(i));
  }
  for (int i = 0; i < 10; ++i) {
    delete files1[i];
  }
  delete[] files;
  //-----------常见逻辑错误---------------
  //①无限循环
  //错误:(无终止条件)
  for (int i = 0; i < 10;) {
    qDebug() << "Looping...";
    // 忘记写i++
  }
  //错误:死循环(条件恒为真)
  while (true) {
    //代码块          未提供退出机制
  }
  //解决办法
  // 增加i++
  for (int i = 0; i < 10; i++) {
    qDebug() << "Looping..." << i;
  }
  //使用break或return退出循环
  while (true) {
    if (data.isEmpty()) break;  // 条件满足时退出
  }
  //②数据/容器越界访问
  // 错误:访问越界(索引0~9,但循环到i=10)
  QVector<int> numbers(10);
  for (int i = 0; i <= 10; ++i) {  // ӦΪi < 10
    numbers[i] = i;                // i=10时越界
    // 错误:使用空容器
    QStringList names;
    qDebug() << names[0];  // 访问空容器的第一个元素
    //解决办法
    //使用安全的访问方法(如at()代替[])
    qDebug() << numbers.at(10);
    //检查容器是否为空
    if (!names.isEmpty()) {
      qDebug() << names[0];
    }
  // 2.未初始化指针
  QLabel *label4;
@@ -97,7 +218,9 @@
  class MyClass1 {
   public:
    QWidget *widget;
    MyClass1(const MyClass1 &other) { widget = other.widget; }  // 错误:浅拷贝
      MyClass1(const MyClass1 &other) {
        widget = other.widget;
      }  // 错误:浅拷贝
  };
  // 修复:深拷贝或禁用拷贝构造函数
Test/errorexample.h
@@ -3,11 +3,11 @@
#include <QObject>
class errorexample
{
class errorexample {
    Q_OBJECT
public:
    errorexample();
  void createLeak();
};
#endif // ERROREXAMPLE_H
Test/linestyle.cpp
File was deleted