STL 容器在配置記憶體時,需區分「原始記憶體分配」與「物件建構」。`
| 函式 | 用途 |
|---|---|
uninitialized_copy | 將範圍 `[first, last)` 複製到未初始化記憶體 `result`,建構物件 |
uninitialized_fill | 在 `[first, last)` 以值 `x` 建構物件 |
uninitialized_fill_n | 從 `first` 起對 `n` 個位置以值 `x` 建構 |
uninitialized_move | (C++17) 移動建構 |
destroy / destroy_n | 析構物件(不釋放記憶體) |
對 **POD 類型**(Plain Old Data,如 `int`、`char`、簡單結構體),物件建構等同於 `memcpy`/`memmove`,無需呼叫建構函式。STL 利用 `_type_traits`(或 C++11 `std::is_trivially_copyable`)在編譯期分派:
// 簡化版邏輯
template <class InputIt, class ForwardIt>
ForwardIt uninitialized_copy(InputIt first, InputIt last, ForwardIt result) {
using ValueType = typename std::iterator_traits<ForwardIt>::value_type;
if constexpr (std::is_trivially_copyable_v<ValueType>) {
// POD:直接記憶體複製
return (ForwardIt)std::memmove(result, first, (last - first) * sizeof(ValueType));
} else {
// 非 POD:逐個 placement new 建構
ForwardIt cur = result;
try {
for (; first != last; ++first, ++cur)
::new (static_cast<void*>(&*cur)) ValueType(*first);
return cur;
} catch (...) {
// 例外安全:已建構的物件需析構
for (ForwardIt it = result; it != cur; ++it)
(*it).~ValueType();
throw;
}
}
}
標準庫對 `char`、`wchar_t`(及 `signed char`、`unsigned char`)提供 `memmove` 特化,極致優化字串/緩衝區操作:
inline char* uninitialized_copy(const char* first, const char* last, char* result) {
std::memmove(result, first, last - first);
return result + (last - first);
}
非 POD 類型建構時,若第 N 個物件建構拋出例外,前 N-1 個已建構物件**必須被析構**,避免資源洩漏。標準庫實作以 `try-catch` 區塊確保強烈例外安全。
容器實際使用 `allocator_traits::construct`/`destroy`,進一步封裝 placement new 與析構呼叫,支援自訂配置器。
記憶體輔助操作是 STL 容器高效能的基石。它們在「原始位元組」與「C++ 物件」之間架起橋樑,結合 POD 優化、例外安全、配置器抽象,展現了 C++「零開銷抽象」的精髓。實務中**直接使用標準庫**,但理解其原理是進階 C++ 開發者的必修課。