一、 編程語言 (C++)
1. C++基礎語法(數據類型、模板、命名空間)
是什么: 這是構建C++程序的基石。數據類型定義了變量存儲的數據種類和大小;模板允許編寫與數據類型無關的通用代碼;命名空間用于避免大型項目中的名稱沖突。
如何理解:
數據類型: 如?
int
,?double
,?char
?是基礎類型;std::string
,?std::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_ptr
,?std::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
?和訪問控制符?public
,?private
,?protected
?實現。在您的項目中,每個模塊的類設計都體現了封裝思想。繼承: 允許一個新類(派生類)繼承另一個類(基類)的屬性和方法,實現代碼復用和層次化設計。如?
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::vector
,?std::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. 事件過濾器
是什么: 一種更高級的事件處理機制,允許一個對象監視并攔截發送給另一個對象的事件。
如何理解: 比如主窗口可以安裝事件過濾器來監聽所有子控件的事件(如鼠標點擊、按鍵),并在事件到達目標控件之前先進行處理或過濾掉。
如何使用:
在監視者對象中重寫?
eventFilter(QObject *watched, QEvent *event)
?方法。調用?
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: 分布式。每個開發者都有完整的倉庫克隆。常用命令:
clone
,?add
,?commit
,?push
,?pull
,?branch
,?merge
。SVN: 集中式。只有一個中央倉庫。常用命令:
checkout
,?update
,?commit
。
如何理解:?代碼的“時光機”。允許回退到任何歷史版本,并行開發不同功能(分支),解決代碼沖突,追蹤誰在何時改了什麼。
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
)。另一個設備向這個主題發布消息。代理服務器負責將消息轉發給所有訂閱了該主題的設備。實現了發布者和訂閱者的解耦。