📅  最后修改于: 2023-12-03 15:08:52.150000             🧑  作者: Mango
在C++标准库中,有一个非常常用的可变大小数组容器std::vector
。但在某些情况下,我们可能需要自己实现一个类似于std::vector
的容器类,满足我们的特定需求。本文将介绍如何在C++中实现自己的Vector
类。
在实现Vector
类之前,我们需要先了解std::vector
的基本原理。std::vector
是一种使用动态内存分配实现的可变大小数组容器。容器的大小可以在运行时动态调整,不需要在编写代码时就确定。
我们可以使用模板类来定义自己的Vector
类,以支持不同类型的元素。下面是一个基本的Vector
类定义:
template<typename T>
class Vector {
public:
// 构造函数和析构函数
Vector();
Vector(size_t size);
Vector(size_t size, const T& value);
~Vector();
// 元素访问函数
T& operator[](size_t index);
const T& operator[](size_t index) const;
T& front();
const T& front() const;
T& back();
const T& back() const;
// 容量函数
bool empty() const;
size_t size() const;
size_t capacity() const;
void reserve(size_t new_capacity);
// 修改容器
void clear();
void push_back(const T& value);
void pop_back();
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
void resize(size_t new_size);
void swap(Vector& other);
private:
T* data_;
size_t size_;
size_t capacity_;
};
此类定义了Vector
类的基本函数和数据成员。其中,data_
是一个指向存储元素的连续内存区域的指针,size_
是容器中元素的个数,capacity_
是当前分配内存的总容量,即可容纳元素的数量。
我们需要为Vector
定义几个构造函数和一个析构函数,以支持不同的初始化方式。
template<typename T>
Vector<T>::Vector() {
data_ = nullptr;
size_ = 0;
capacity_ = 0;
}
template<typename T>
Vector<T>::Vector(size_t size) {
data_ = new T[size];
size_ = capacity_ = size;
}
template<typename T>
Vector<T>::Vector(size_t size, const T& value) {
data_ = new T[size];
for (size_t i = 0; i < size; ++i)
data_[i] = value;
size_ = capacity_ = size;
}
template<typename T>
Vector<T>::~Vector() {
delete[] data_;
}
接下来,我们需要定义一些容量函数,以使用户能够查询容器的状态。容量函数的实现相对简单,只需要返回size_
或capacity_
即可。
template<typename T>
bool Vector<T>::empty() const {
return size_ == 0;
}
template<typename T>
size_t Vector<T>::size() const {
return size_;
}
template<typename T>
size_t Vector<T>::capacity() const {
return capacity_;
}
template<typename T>
void Vector<T>::reserve(size_t new_capacity) {
if (new_capacity > capacity_) {
T* new_data = new T[new_capacity];
for (size_t i = 0; i < size_; ++i)
new_data[i] = data_[i];
delete[] data_;
data_ = new_data;
capacity_ = new_capacity;
}
}
reserve
函数用于预留内存空间,以在添加元素时避免频繁的重新分配内存。
Vector
类中,我们需要定义一些函数来访问容器中的元素。这些函数包括随机访问函数和访问容器开头和结尾元素的函数。这里,为了方便起见,我们只实现了随机访问函数和开头/结尾元素访问函数。
template<typename T>
T& Vector<T>::operator[](size_t index) {
return data_[index];
}
template<typename T>
const T& Vector<T>::operator[](size_t index) const {
return data_[index];
}
template<typename T>
T& Vector<T>::front() {
return data_[0];
}
template<typename T>
const T& Vector<T>::front() const {
return data_[0];
}
template<typename T>
T& Vector<T>::back() {
return data_[size_ - 1];
}
template<typename T>
const T& Vector<T>::back() const {
return data_[size_ - 1];
}
最后,我们需要定义一些函数来修改Vector
容器的状态。这些函数包括添加元素、删除元素、清空容器和调整容器大小。我们在这里只定义了push_back
和pop_back
函数。
template<typename T>
void Vector<T>::push_back(const T& value) {
if (size_ >= capacity_)
reserve(capacity_ == 0 ? 1 : capacity_ * 2);
data_[size_++] = value;
}
template<typename T>
void Vector<T>::pop_back() {
if (!empty())
--size_;
}
迭代器是一个重要的概念,也是容器类必须实现的。由于本文篇幅有限,这里不再讨论,在此仅提醒读者在实现Vector
类时记得包含迭代器的实现,以满足C++ STL中的迭代器标准。
本文介绍了如何在C++中实现自己的Vector
类。在实现时,我们需要定义不同的函数和数据成员,以支持不同的操作和状态查询。虽然本文只实现了Vector
的基本功能,但是这些功能已经足够支持一些简单的数据处理需求了。对于更高级的数据处理需求,读者可以在自己的应用中添加更多的功能。