教學版實現 (裸指針手動管理)
template <typename T>
class MyArray {
T* data_ = nullptr;
size_t size_ = 0;
size_t capacity_ = 0;
void reallocate(size_t newCap) {
T* newData = new T[newCap];
for (size_t i = 0; i < size_; ++i) newData[i] = std::move(data_[i]);
delete[] data_;
data_ = newData;
capacity_ = newCap;
}
public:
MyArray() = default;
~MyArray() { delete[] data_; }
// 複製/移動語義 (規則五)
MyArray(const MyArray& other) : size_(other.size_), capacity_(other.size_) {
data_ = new T[capacity_];
for (size_t i = 0; i < size_; ++i) data_[i] = other.data_[i];
}
MyArray& operator=(const MyArray& other) {
if (this != &other) {
MyArray tmp(other);
swap(tmp);
}
return *this;
}
MyArray(MyArray&& other) noexcept : data_(other.data_), size_(other.size_), capacity_(other.capacity_) {
other.data_ = nullptr; other.size_ = other.capacity_ = 0;
}
MyArray& operator=(MyArray&& other) noexcept {
if (this != &other) { delete[] data_; data_ = other.data_; size_ = other.size_; capacity_ = other.capacity_; other.data_ = nullptr; }
return *this;
}
void swap(MyArray& other) noexcept {
std::swap(data_, other.data_);
std::swap(size_, other.size_);
std::swap(capacity_, other.capacity_);
}
// 核心操作
T& operator[](size_t idx) {
if (idx >= size_) throw std::out_of_range("index");
return data_[idx];
}
const T& operator[](size_t idx) const { return const_cast<MyArray*>(this)->operator[](idx); }
void push_back(const T& val) {
if (size_ == capacity_) reallocate(capacity_ ? capacity_ * 2 : 1);
data_[size_++] = val;
}
void push_back(T&& val) {
if (size_ == capacity_) reallocate(capacity_ ? capacity_ * 2 : 1);
data_[size_++] = std::move(val);
}
size_t size() const { return size_; }
bool empty() const { return size_ == 0; }
};
測試代碼
int main() {
MyArray<int> a;
a.push_back(11); a.push_back(22); a.push_back(33); a.push_back(55);
a[0] = 44;
for (size_t i = 0; i < a.size(); ++i) std::cout << a[i] << '\n';
}
關鍵設計點
| 要點 | 說明 |
| 指數增長 | 容量翻倍 (×2) 攤銷 O(1) 擴容成本 |
| 移動語義 | C++11 push_back(T&&) 避免昂貴拷貝 |
| 規則五 | 析構/拷貝構造/拷貝賦值/移動構造/移動賦值 全部實現 |
| 異常安全 | reallocate 先分配再移動,失敗不影響原數據 |
| 迭代器 | 教學版省略;生產級需提供 begin/end 支援範圍 for |
現代 C++ 最佳實踐:直接用 std::vector
#include <vector>
std::vector<int> v;
v.push_back(11); v.push_back(22); v.push_back(33); v.push_back(55);
v[0] = 44;
for (int x : v) std::cout << x << '\n';
std::vector 經過數十年優化:SSO、分配器支援、調試檢查、SIMD 優化、ABI 穩定。
- 手寫容器僅用於:教學理解 RAII/移動語義、極度受限嵌入式 (禁用 STL)、特殊內存佈局需求。
- 若需固定容量棧上分配:
std::array 或 boost::container::static_vector。