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

C++/QT 开发技能树详解

一、 编程语言 (C++)

1. C++基础语法(数据类型、模板、命名空间)

  • 是什么: 这是构建C++程序的基石。数据类型定义了变量存储的数据种类和大小;模板允许编写与数据类型无关的通用代码;命名空间用于避免大型项目中的名称冲突。

  • 如何理解

    • 数据类型: 如 intdoublechar 是基础类型;std::stringstd::vector 是标准库定义的复杂类型。理解它们的内存占用和操作代价对性能优化至关重要。

    • 模板: 可以把它理解为一个“代码模具”。比如您项目中的 std::vector<int> 和 std::vector<std::string>,编译器会根据这个“模具”生成两份分别处理int和string的代码。这是C++实现泛型编程的核心。

    • 命名空间: 类似于文件系统的目录。std::cout 意味着在std这个“目录”下找cout。您也可以创建自己的命名空间来组织代码,防止和第三方库的符号冲突。

  • 如何使用

    • 在定义变量时选择最合适的数据类型。

    • 使用模板来编写通用函数(如 template <typename T> T max(T a, T b))和通用类。

    • 在自己的库或模块中使用 namespace MyProject { ... } 来封装代码。使用 using namespace std; 需谨慎,尤其在头文件中。

2. 指针

  • 是什么: 指针是一个变量,其值是另一个变量的内存地址。

  • 如何理解: 指针就是地址

它提供了直接操作内存的能力,非常强大但也容易出错(如空指针、野指针)。在C++中,它常用于动态内存分配、数组遍历、函数传参(避免拷贝大对象)等。

  • 如何使用

    • 动态分配内存:int *ptr = new int;,记得用 delete ptr; 释放。

    • 传递函数参数:void modifyValue(int *ptr) { *ptr = 10; },允许函数修改外部变量的值。

    • 访问数组:数组名本质上就是一个指向数组首元素的指针。

    • 现代C++建议: 优先使用智能指针 (std::unique_ptrstd::shared_ptr),它们可以自动管理内存生命周期,极大减少内存泄漏的风险。

3. Lambda 表达式

  • 是什么: 一种匿名函数对象,可以在代码中就地定义短小的函数,而无需正式声明一个函数。

  • 如何理解: 它类似于JavaScript中的箭头函数。它捕获上下文变量、接受参数、并有一个函数体。它使得代码更简洁,尤其是在与STL算法配合时。

  • 如何使用

    • 基本语法:[capture] (parameters) -> return_type { function_body }

    • 捕获列表 [capture] 是关键:

      • [=]:以值的方式捕获所有外部变量。

      • [&]:以引用的方式捕获所有外部变量。

      • [a, &b]:以值捕获a,以引用捕获b。

    • 示例:与 std::sort 或 std::for_each 配合使用。

      std::vector<int> vec = {4, 2, 5, 1};
      std::sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; }); // 降序排列

4. 面向对象:封装、继承、多态

  • 是什么: 面向对象编程的三大核心特性。

  • 如何理解与使用

    • 封装: 将数据(属性)和操作数据的方法(函数)绑定在一起,并隐藏内部实现细节,只暴露接口。通过 class 和访问控制符 publicprivateprotected 实现。在您的项目中,每个模块的类设计都体现了封装思想。

    • 继承: 允许一个新类(派生类)继承另一个类(基类)的属性和方法,实现代码复用和层次化设计。如 class Dog : public Animal {}

    • 多态: 允许不同类的对象对同一消息做出不同的响应。通常通过基类的虚函数指针/引用来实现。

      class Shape {
      public:virtual void draw() = 0; // 纯虚函数,抽象基类
      };
      class Circle : public Shape {
      public:virtual void draw() override { /* 画一个圆 */ }
      };
      // 多态的使用
      Shape *shape = new Circle();
      shape->draw(); // 调用的是 Circle::draw()
    • 在您项目中的应用: QT的整个 widget 系统就是基于继承和多态。QPushButton 继承自 QWidget,您可以重写 paintEvent 等虚函数来实现自定义UI。


二、 内存管理

1. 堆栈机制

  • 是什么: 程序运行时内存管理的两种基本方式。

  • 如何理解

    • : 由编译器自动分配和释放。存放局部变量、函数参数等。分配速度快,但空间有限,生命周期与函数作用域绑定。

    • : 由程序员手动分配和释放(new/delete 或 malloc/free)。空间大,分配速度慢,生命周期由程序员控制,管理不当会导致内存泄漏或野指针。

  • 如何使用: 小型、生命周期短的变量用栈。大型对象、需要动态控制生命周期的对象用堆(并尽量用智能指针管理)。

2. 手动内存管理

  • 是什么: 使用 new 和 delete 成对操作来在堆上分配和释放内存。

  • 如何理解: 谁申请,谁释放。忘记释放会导致内存泄漏;释放后再次使用会导致未定义行为。在复杂流程中,确保在每一个分支路径上都正确释放内存非常具有挑战性。

  • 如何使用: 强烈建议在现代C++项目中避免直接使用 new/delete。使用 std::vectorstd::string 等容器以及 std::unique_ptr 和 std::shared_ptr 等智能指针来自动化内存管理。您在“性能优化”中提到的“内存池”是更高级的手动内存管理技术,用于特定性能敏感场景。


三、 QT 框架

1. 信号和槽

  • 是什么: QT的核心机制,用于对象之间的通信。它是一种类型安全的“观察者模式”。

  • 如何理解: 当某个对象(发送者)的状态发生变化时,它会发射一个信号。另一个对象(接收者)的函数可以对这种变化做出响应。它们通过 QObject::connect 函数连接。

  • 如何使用

    // 声明
    class Sender : public QObject {Q_OBJECT
    signals:void valueChanged(int newValue);
    };
    class Receiver : public QObject {Q_OBJECT
    public slots:void handleValueChange(int value) { ... }
    };
    // 连接
    Sender s; Receiver r;
    QObject::connect(&s, &Sender::valueChanged, &r, &Receiver::handleValueChange);
    // 触发
    emit s.valueChanged(10); // 此后,r.handleValueChange(10) 会被自动调用
    • 在您项目中的应用: 这是QT程序事件驱动的基石。按钮点击、定时器超时、网络数据到达等,都是通过信号和槽来通知和处理的。

2. 事件过滤器

  • 是什么: 一种更高级的事件处理机制,允许一个对象监视并拦截发送给另一个对象的事件。

  • 如何理解: 比如主窗口可以安装事件过滤器来监听所有子控件的事件(如鼠标点击、按键),并在事件到达目标控件之前先进行处理或过滤掉。

  • 如何使用

    1. 在监视者对象中重写 eventFilter(QObject *watched, QEvent *event) 方法。

    2. 调用 watchedObject->installEventFilter(filterObject); 进行安装。

    • 在您项目中的应用: 可用于实现全局快捷键、自定义鼠标行为、验证输入等。

3. 多线程编程

  • 是什么: 使用 QThread 等类来并发执行任务,防止耗时操作阻塞主线程(UI线程)。

  • 如何理解: QT推荐使用工作线程模式,而非继承QThread。即将一个的工作对象(继承自QObject)移动到一个线程中,通过信号和槽与主线程通信。

  • QThread *thread = new QThread;
    Worker *worker = new Worker; // Worker 是一个QObject
    worker->moveToThread(thread); // 关键步骤
    // 连接信号槽:启动线程、开始工作、汇报进度、结束线程
    connect(thread, &QThread::started, worker, &Worker::doWork);
    connect(worker, &Worker::resultReady, this, &MainWindow::handleResult);
    connect(worker, &Worker::finished, thread, &QThread::quit);
    connect(thread, &QThread::finished, thread, &QThread::deleteLater);
    thread->start();
    • 在您项目中的应用: 您在“广告机系统”中明确提到了“使用QThread开发专用工作线程,处理网络IO和文件操作”,这正是该模式的典型应用。


四、 图像处理 (OpenCV)

1. 图像滤波(如高斯滤波)

  • 是什么: 使用一个“核”在图像上滑动,计算邻域像素的加权平均值,用于去噪平滑

  • 如何理解: 高斯滤波的权重服从高斯分布(正态分布),中心点权重最大,越远权重越小。能很好地消除高斯噪声,并保留更多的图像边缘信息 compared to mean filter。

  • 如何使用: cv::GaussianBlur(src, dst, Size(5,5), 0);

2. 边缘检测(如Canny)

  • 是什么: 识别图像中亮度变化剧烈的点,这些点通常对应物体的边缘

  • 如何理解: Canny边缘检测是一个多阶段的算法(噪声去除->计算梯度->非极大值抑制->双阈值筛选),结果是干净、连续的边缘。

  • 如何使用: cv::Canny(src, edges, threshold1, threshold2);

3. 特征提取与匹配

  • 是什么: 特征是图像中具有独特性的局部结构(如角点、斑块)。匹配是在不同图像中寻找相同特征的过程。

  • 如何理解: 就像人的“痣”或“脸部轮廓”是特征。SIFT、SURF、ORB等算法可以提取这些特征并生成一个描述子向量。通过比较描述子向量的距离,可以判断两个特征是否匹配。

  • 在您项目中的应用: 您在“纺织面料疵点检测”项目中,提取疵点的“特征向量”就是为了后续能够对疵点进行分类和识别。


五、 开发工具 & 其他

1. 版本控制 (Git/SVN)

  • 是什么: 记录代码变更历史、协同开发的工具。

  • 核心概念

    • Git: 分布式。每个开发者都有完整的仓库克隆。常用命令:cloneaddcommitpushpullbranchmerge

    • SVN: 集中式。只有一个中央仓库。常用命令:checkoutupdatecommit

  • 如何理解: 代码的“时光机”。允许回退到任何历史版本,并行开发不同功能(分支),解决代码冲突,追踪谁在何时改了什麼。

2. 数据库 (MySQL/SQLite)

  • 是什么: 结构化数据存储和管理系统。

  • 核心概念与使用

    • SQLite: 轻量级,嵌入式的数据库,整个库就是一个文件。非常适合桌面应用、移动应用(如您的QT终端程序)作为本地存储。

    • MySQL: 强大的客户端-服务器型数据库,支持高并发、大规模数据。适合作为Web应用或分布式系统(如您的广告机管理系统)的后端数据库。

    • CRUD: 增(INSERT)、删(DELETE)、改(UPDATE)、查(SELECT)是基本操作。

    • 索引: 加速查询的数据结构,理解它对于“优化数据库查询性能”至关重要。

3. 网络协议 (TCP/UDP/HTTP/MQTT)

  • 是什么: 设备之间通信的规则。

  • 如何理解与使用

    • TCP: 面向连接、可靠、有序的字节流传输。像打电话,需要建立连接,保证对方能听到。用于需要可靠性的场景(如文件传输、网页浏览)。

    • UDP: 无连接、不可靠的数据报传输。像发广播,不保证对方收到。用于实时性要求高、可容忍少量丢失的场景(如视频通话、游戏)。

    • HTTP: 基于TCP的应用层协议,是Web通信的基础(请求-响应模型)。

    • MQTT: 轻量级的发布-订阅消息协议,专为物联网设计。您在广告机项目中的核心贡献就是基于此协议。

      • 理解发布-订阅: 设备(客户端)连接到代理服务器(如EMQX)。设备订阅它感兴趣的主题(如 device/001/temperature)。另一个设备向这个主题发布消息。代理服务器负责将消息转发给所有订阅了该主题的设备。实现了发布者和订阅者的解耦

http://www.dtcms.com/a/344971.html

相关文章:

  • 钉钉 Stream 模式SpringBoot接入配置与事件监听
  • Maxscript如何清理3dMax场景?
  • react样式问题
  • git旧仓库迁移到新仓库
  • [系统架构设计师]安全架构设计理论与实践(十八)
  • Web3与AI语境下的审美积累:HAQQ品牌识别解析
  • 多人编程新方式:cpolar 让 OpenHands 远程开发更轻松
  • 区块链技术原理(17)-以太坊网络
  • SpringBoot中的条件注解
  • 常用三角函数公式推导体系
  • LLM应用场景能力边界趋势全览
  • 从系统修复到硬件检测的技术实测
  • [antv-x6] 文档链接
  • 08高级语言逻辑结构到汇编语言之逻辑结构转换 continue break 完结汇编按逻辑结构
  • RCE的CTF题目环境和做题复现第4集
  • 驱动(二)系统移植
  • 根据webpack设计原理手写一个简版webpack
  • 亚马逊广告优化新逻辑:从人工苦力到AI智能的进化之路
  • K8S的部署与常用管理
  • http请求有哪些?
  • 文件相关操作的函数和文件操作
  • 使用tensorRT8部署yolov5目标检测模型(1)
  • 深入解析 Docker 镜像构建与性能优化实践指南
  • SSM从入门到实战: 2.6 MyBatis缓存机制与性能优化
  • 双发 ARP 测试与实践:从原理到生产验证
  • PHP 函数的参数顺序,它们是随机的吗?
  • 数学建模论文注意点
  • 华盛顿大学GeoAI本土化实践:五大实验贯穿预测、检测、生成、推理与偏差审视
  • 碧海琴魂,孤独与纯粹的永恒绝唱——《海上钢琴师》鉴赏
  • 双摄工业相机镜头切换与同步曝光技术方案