引言
在第一篇博客中,深入淺出之STL源碼分析1_vector基本操作-CSDN博客
我們將引出下面的幾個問題
1.剛才我提到了我的編譯器版本是g++ 11.4.0,而我們要講解的是STL(標準模板庫),那么二者之間的關系是什么?STL安裝后我們到哪里去看源碼?
2.我們引入了頭文件#include<vector>
這里的vector的內容是什么?
3.vector<int> test_vector; 這中定義方式是干什么?<>的作用是什么?
4.test_vector.push_back(22); 對于stl源碼底層到底做了什么?把對應的數據插入到了哪個地址了?
什么時候分配的虛擬內存?什么時候擴容?什么時候會分配物理內存?
下面我們來重點來說明下問題1.
stl和標準庫的關系
標準庫的代碼都統一在一個命名空間std(Standard的縮寫)中,也就是說std命名空間下的內容屬于C++標準庫(Standard Library),但是并非全部屬于標準模版庫(standard template library, stl),也就是標準模板庫只是標準庫的一部分。
std 是 C++ 標準庫的所有組件所在的命名空間,包含以下類別:
- ?STL(標準模板庫)?:容器、迭代器、算法、函數對象等。
- ?非 STL 的標準庫組件:輸入輸出(iostream)、字符串(std::string)、智能指針、多線程(std::thread)、異常處理、類型工具(type_traits)等。
stl的實現與編譯器的關系
C++ 標準庫(含 STL)的源碼由 ?編譯器廠商或開源社區實現,不同編譯器使用不同的實現:
- ?GCC:使用 ?**libstdc++**?(GNU 標準 C++ 庫),源碼路徑如 /usr/include/c++/版本號
- ?Clang:默認使用 libstdc++,但可配置為 ?**libc++**?(LLVM 項目開發)。
- ?MSVC:使用 ?Microsoft STL,僅限 Windows。
- MinGW 是gcc的windows版本。
每個實現的源碼結構和優化策略不同,但均遵循 C++ 標準。
stl源碼何時安裝到linux?
STL 源碼在 ?安裝編譯器時自動部署,屬于編譯器工具鏈的一部分:
- ?安裝 GCC:會同時安裝其標準庫(libstdc++)的 ?頭文件(.h/.hpp)?? 和 ?預編譯二進制庫(.so)?。
- ?頭文件路徑:如?/usr/include/c++/11/vector(GCC 11.4.0 版本)。
- ?二進制庫路徑:如?/usr/lib/gcc/aarch64-linux-gnu/11/libstdc++.so。
一個疑問?就是一般我們的stl都是頭文件的形式,我們只是需要.h文件就可以使用了,為什么還有一個動態庫呢?
?/usr/lib/gcc/aarch64-linux-gnu/11/libstdc++.so,哪些實現需要放在.cpp中并且形成動態庫呢?
雖然 STL 的模板代碼(如?vector、deque)?完全在頭文件中實現,但標準庫中還有以下內容需要編譯為二進制庫:
? 類別 ? | ? 示例 ? | ?**為什么需要二進制庫?**? |
? 運行時支持 ? | std::exception 、 std::type_info | 需要全局唯一的 RTTI(運行時類型信息)和異常處理機制。 |
? 動態內存管理 ? | operator new 、 operator delete | 全局內存分配器的實現需要跨編譯單元共享。 |
? 輸入輸出流 ? | std::cout 、 std::fstream | 底層文件操作和緩沖區管理需要與操作系統交互,無法完全用頭文件實現。 |
? 多線程支持 ? | std::thread 、 std::mutex | 依賴操作系統原生線程 API(如 pthread),需封裝為二進制接口。 |
? 數學函數 ? | std::sin 、 std::sqrt | 某些數學函數需要鏈接到系統數學庫(如 libm )。 |
? C 標準庫兼容層 ? | std::printf 、 std::malloc | C 標準庫函數(如 printf )的實現需要預編譯。 |