在 C++ 開發中,動態陣列的管理一直是核心課題。早期 MFC 開發者常使用 CArray<>,但隨著 C++ 標準化(1998)與 STL 的普及,::std::vector<> 已成為跨平台、高效且符合現代 C++ 設計哲學的最佳選擇。本文深入剖析 vector 的優勢、核心介面與實務注意事項,助你寫出更安全、可維護的程式碼。
CArray<> 綁定 MFC,僅限 Windows 平台;std::vector<> 屬於 C++ 標準庫,任何符合標準的編譯器(GCC、Clang、MSVC 等)皆可使用,程式碼可移植性大幅提升。
CArray<> 繼承 CObject 以支援序列化,違反「不為不使用的功能付費」原則。更嚴重的是,它不是正確的值型別:
CArray<int,int> b(a); // 錯誤,需用 Copy()b = a; // 錯誤b == a; // 錯誤若類別包含 CArray 成員,編譯器無法自動產生拷貝建構子與指派運算子,迫使開發者手寫大量樣板碼,維護成本極高。
相反地,std::vector<> 是設計完善的值型別:
operator==、operator< 等)CArray<> 無法直接搭配 <algorithm>;vector 的迭代器滿足 RandomAccessIterator,可直接使用 std::sort、std::find、std::transform 等上百種演算法:
static const int init_vals[] = {3, 1, 4, 1, 6, 9};
std::vector<int> v(init_vals, init_vals + 6);
*std::find(v.begin(), v.end(), 6) = 5; // 將 6 改為 5
std::sort(v.begin(), v.end()); // 排序
| 型別 | 說明 |
|---|---|
value_type | 元素型別 T |
iterator / const_iterator | 可修改 / 唯讀的隨機存取迭代器 |
reverse_iterator / const_reverse_iterator | 反向迭代器 |
vector<T> v; // 空向量
vector<T> v(n, val); // n 個 val
vector<T> v(other); // 拷貝建構
vector<T> v(first, last); // 區間建構(支援指標、迭代器)
v.assign(first, last); // 區間指派
v.assign(n, val); // 填充指派
v.at(i) // 邊界檢查,越界拋出 std::out_of_range
v[i] // 無檢查,效能較高
v.front() // 首元素
v.back() // 尾元素
v.size() // 目前元素數
v.capacity() // 已配置空間可容納元素數
v.empty() // 是否為空
v.reserve(n) // 預留至少 n 個元素空間,避免重複配置
v.resize(n) // 調整元素數為 n(不足則填充,超過則截斷)
v.clear() // 清空元素,capacity 不變
v.shrink_to_fit() // C++11:請釋放多餘容量(非強制)
v.push_back(val); // 尾部新增
v.insert(pos, val); // 指定位置插入
v.insert(pos, n, val); // 插入 n 個 val
v.insert(pos, first, last); // 插入區間
v.pop_back(); // 移除尾部
v.erase(pos); // 移除單一元素
v.erase(first, last); // 移除區間
關鍵特性:push_back/insert 觸發擴容時,容量呈指數成長(通常 1.5~2 倍),攤還時間複雜度 O(1)。刪除操作不會縮減 capacity()。
v.begin() / v.end() // 正向區間 [begin, end)
v.rbegin() / v.rend() // 反向區間 [rbegin, rend)
// 範例:列印所有元素
for (auto it = v.begin(); it != v.end(); ++it) std::cout << *it << '\n';
// 反向列印
for (auto it = v.rbegin(); it != v.rend(); ++it) std::cout << *it << '\n';
因 vector 記憶體連續,&v[0] 或 v.data()(C++11)可直接傳遞給 C API(如 WaitForMultipleObjects)。
v.swap(other); // O(1) 交換內容,不拋出異常
std::swap(v, other); // 同樣高效
swap 是實作「強烈異常安全」的關鍵技巧(Copy-and-swap idiom)。
reserve():避免多次重新配置與拷貝。
std::vector<int> v;
v.reserve(10000);
for (int i = 0; i < 10000; ++i) v.push_back(i); // 零重新配置
reserve 與 resize:前者只配置原始空間,後者真正建構物件。
vector(v.begin(), v.end()).swap(v) 或 C++11 shrink_to_fit()。
std::deque 或 std::list(但失去連續記憶體優勢)。
new[]/delete[] 或 malloc/realloc:vector 以 RAII 封裝記憶體管理,杜絕洩漏與雙重釋放。
std::vector<> 不只是動態陣列的替代品,更是現代 C++ 資源管理的基石。它提供:
swap、reserve、shrink_to_fit在新專案中,請毫不猶豫地選擇 std::vector<>;在舊代碼中,漸進式替換 CArray、手動記憶體管理將顯著降低維護成本並提升程式碼品質。