当前位置: 首页> 房产> 建材 > 安阳门户网站_制作微信小程序步骤_北京seo网站推广_免费十八种禁用网站

安阳门户网站_制作微信小程序步骤_北京seo网站推广_免费十八种禁用网站

时间:2025/7/27 7:39:10来源:https://blog.csdn.net/2302_80836956/article/details/145930656 浏览次数:0次
安阳门户网站_制作微信小程序步骤_北京seo网站推广_免费十八种禁用网站

文章目录

  • 1. 引言
  • 2. vector的核心设计
  • 3. vector的常用接口介绍
    • 3.1 构造函数和析构函数
      • 3.1.1 默认构造函数
      • 3.1.2 带初始容量的构造函数
      • 3.1.3 析构函数
    • 3.2 拷贝构造函数和拷贝赋值运算符
      • 3.2.1 拷贝构造函数
      • 3.2.2 拷贝赋值运算符
    • 3.5 数组长度调整和动态扩容
      • 3.5.1 调整大小(resize)
      • 3.5.2 缩减容量(shrink_to_fit)
      • 3.5.3 动态扩容(reserve)
    • 3.6 添加元素
      • 3.6.1 添加左值元素
      • 3.6.2 添加右值元素
    • 3.7 删除元素
      • 3.7.1 删除指定位置元素
      • 3.7.2 尾删
    • 3.8 元素访问
      • 3.8.1 通过下标访问元素
    • 3.9 迭代器支持
  • 4. 总结
  • 5. 附录
    • 5.1 测试用例

1. 引言

std::vector 是 C++ 中最常用的动态数组容器。为了更好地理解其内部机制,我们将从头实现一个功能更完整的 vector,并逐步优化它。本文不仅会实现基本功能,还会深入探讨一些高级特性,例如异常安全性、迭代器支持和自定义分配器。

2. vector的核心设计

根据 STLvector 的设计。一个 vector 的核心是动态数组,它需要以下成员变量:

  • _start :指向动态数组当前存储元素的第一个位置。
  • _finish :指向动态数组当前存储元素的最后一个位置。
  • _end_of_storage :指向动态数组容量的最后一个位置。

具体的代码实现路径如下:

template<class T>
class vector
{
public:typedef T* iterator;typedef const T* const_iterator;iterator begin(){return _start;}iterator end(){return _finish;}const_iterator begin() const{return _start;}const_iterator end() const{return _finish;}//构造函数vector(){}//类模板的成员函数,也可以是一个函数模板template <class InputIterator>vector(InputIterator first,InputIterator last){while (first != last){push_back(*first);++first;}}vector(size_t n, const T& val = T()){reserve(n);for (size_t i = 0;i < n; i++){push_back(val);}}/*vector(int n, const T& val = T()){reserve(n);for (int i = 0; i < n; i++){push_back(val);}}*/vector(std::initializer_list<T> il){reserve(il.size());for (auto& e : il){push_back(e);}}vector(const vector<T>& v){reserve(v.capacity());for (auto& e : v){push_back(e);}}void swap(vector<T>& tmp){// std 需要在上面将 std域展开std::swap(_start, tmp._start);std::swap(_finish, tmp._finish);std::swap(_endofstorage, tmp._endofstorage);}vector<T>& operator=(vector<T> v){swap(v);return *this;}~vector(){if (_start){delete[] _start;_start = _finish = _endofstorage = nullptr;}}T& operator[](size_t i){assert(i < size());return _start[i];}const T& operator[](size_t i) const{assert(i < size());return _start[i];}size_t size() const{return _finish - _start;}size_t capacity() const{return _endofstorage - _start;}void resize(size_t n, T val = T()){if (n <= size()){_finish = _start + n;}else{reserve(n);while (_finish < _start + n){*_finish = val;++_finish;}}}void reserve(size_t n){if (n > capacity()){size_t oldSize = size();T* tmp = new T[n];if (_start){for (size_t i = 0; i < oldSize; i++){tmp[i] = _start[i];}delete[] _start;}_start = tmp;_finish = _start + oldSize;_endofstorage = _start + n;}}void push_back(const T& x){insert(_finish, x);}bool empty(){return _start == _finish;}void pop_back(){assert(!empty());--_finish;}iterator insert(iterator pos,const T& x){assert(pos >= _start && pos <= _finish);if (_finish == _endofstorage){size_t len = pos - _start;reserve(capacity() == 0 ? 4 : capacity() * 2);pos = _start + len;}iterator i = _finish - 1;while (i >= pos){*(i + 1) = *i;--i;}*pos = x;++_finish;return pos;}iterator erase(iterator pos){assert(pos >= _start && pos < _finish);iterator i = pos + 1;while (i < _finish){*(i - 1) = *i;++i;}_finish--;return pos;}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _endofstorage = nullptr;
};

3. vector的常用接口介绍

3.1 构造函数和析构函数

3.1.1 默认构造函数

初始化一个空的 vector

template <typename T>
Vector<T>::Vector() : (nullptr), size(0), capacity(0) {}

3.1.2 带初始容量的构造函数

允许用户指定初始容量。

template <typename T>
Vector<T>::Vector(size_t initial_capacity): data(new T[initial_capacity]), size(0), capacity(initial_capacity) {}

3.1.3 析构函数

释放动态分配的内存。

template <typename T>
Vector<T>::~Vector() {delete[] data;
}

3.2 拷贝构造函数和拷贝赋值运算符

3.2.1 拷贝构造函数

深拷贝另一个 vector 的内容。

template <typename T>
Vector<T>::Vector(const Vector& other): data(new T[other.capacity]), size(other.size), capacity(other.capacity) {for (size_t i = 0; i < size; ++i) {data[i] = other.data[i]; // 调用 T 的拷贝构造函数}
}

3.2.2 拷贝赋值运算符

先释放当前资源,再深拷贝另一个 vector 的内容。

template <typename T>
Vector<T>& Vector<T>::operator=(const Vector& other) {if (this != &other) {// 创建一个临时对象Vector temp(other);// 交换当前对象和临时对象的内容std::swap(data, temp.data);std::swap(size, temp.size);std::swap(capacity, temp.capacity);}return *this;
}

3.5 数组长度调整和动态扩容

3.5.1 调整大小(resize)

resize 函数用于调整 vector 的大小。如果新大小大于当前容量,则需要扩容;如果新大小小于当前大小,则只需调整 size

template <typename T>
void Vector<T>::resize(size_t new_size) {if (new_size > capacity) {// 如果新大小大于当前容量,需要扩容reserve(new_size);}if (new_size > size) {// 如果新大小大于当前大小,初始化新增元素for (size_t i = size; i < new_size; ++i) {data[i] = T(); // 使用默认构造函数初始化新元素}}size = new_size; // 更新大小
}

3.5.2 缩减容量(shrink_to_fit)

shrink_to_fit 函数用于将 vector 的容量缩减到当前大小,以节省内存。

template <typename T>
void Vector<T>::shrink_to_fit() {if (size < capacity) {// 创建一个临时数组,容量为当前大小T* new_data = new T[size];for (size_t i = 0; i < size; ++i) {new_data[i] = std::move(data[i]); // 移动元素到新数组}// 释放旧数组delete[] data;// 更新指针和容量data = new_data;capacity = size;}
}

注意:这个函数不常用。因为这个函数是请求把多余的内存还给系统,不一定会成功。

3.5.3 动态扩容(reserve)

reserve 函数用于确保 vector 的容量至少为指定值。如果当前容量不足,则扩容。

template <typename T>
void Vector<T>::reserve(size_t new_capacity) {if (new_capacity <= capacity) return; // 如果容量足够,直接返回// 创建新数组T* new_data = new T[new_capacity];for (size_t i = 0; i < size; ++i) {new_data[i] = std::move(data[i]); // 移动元素到新数组}// 释放旧数组delete[] data;// 更新指针和容量data = new_data;capacity = new_capacity;
}

说明:

  • 如果 new_capacity <= capacity,直接返回。如果当前数组容量大于新的数组容量,那么就会直接返回。
  • 否则,创建一个新数组,容量为 new_capacity。再使用 std::move 将元素从旧数组移动到新数组。释放旧数组,并更新 data和capacity

3.6 添加元素

3.6.1 添加左值元素

将元素拷贝到 vector 的头部。

template <typename T>
void Vector<T>::insert(const T& value) {if (size >= capacity) {reserve(capacity == 0 ? 4 : capacity * 2);}data[size++] = value;
}

3.6.2 添加右值元素

将元素拷贝到 vector 的末尾。

template <typename T>
void Vector<T>::push_back(const T& value) {if (size >= capacity) {reserve(capacity == 0 ? 1 : capacity * 2);}data[size++] = value;
}

3.7 删除元素

3.7.1 删除指定位置元素

删除指定位置元素。

iterator erase(iterator pos)
{assert(pos >= _start && pos < _finish);iterator i = pos + 1;while (i < _finish){*(i - 1) = *i;++i;}_finish--;return pos;
}

3.7.2 尾删

删除尾部位置的元素。

void pop_back()
{assert(!empty());--_finish;
}

注意:erase尽量少用。由于erase可以删除任意位置的元素,所以会涉及到大量的数组容量更改操作。这会大幅降低程序效率。

3.8 元素访问

3.8.1 通过下标访问元素

T& operator[](size_t i)
{assert(i < size());return _start[i];
}

3.9 迭代器支持

iterator begin()
{return _start;
}iterator end()
{return _finish;
}const_iterator begin() const
{return _start;
}const_iterator end() const
{return _finish;
}

4. 总结

通过这个详细的实现,我们深入了解了 std::vector 的核心机制,包括动态扩容、拷贝/移动语义、迭代器支持等。

希望这篇博客对你有所帮助!如果有任何问题或建议,欢迎留言讨论。

5. 附录

5.1 测试用例

	void test_vector01(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto ch : v1){cout << ch << " ";}cout << endl;for (int i = 0; i < v1.size(); i++){cout << v1[i] << " ";}cout << endl;v1.pop_back();for (auto ch : v1){cout << ch << " ";}cout << endl;// pop_back只能尾删,v1.pop_back(1)行不通;int n = *v1.begin();cout << n << endl;vector<int>::iterator it1 = v1.begin();vector<int>::iterator it2 = v1.end();while (it1 != it2){cout << *it1++ << " ";}cout << endl;}void test_vector02(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;// 第一种使用迭代器在指定位置插入数字v1.insert(v1.begin() + 1, 26);for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector03(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);vector<int>::iterator it1 = v1.begin();vector<int>::iterator it2 = v1.end();auto x = 0;cin >> x;// 第二种使用迭代器 在指定位置插入指定倍数的数字auto it = find(it1, it2, x);if (it != it2){it = v1.insert(it, 10 * x);cout << *it << endl;}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector04(){vector<int> v1;// 这一遍是模拟实现的// 这里必须使用系统自带的vector,不然程序会报错中止//std::vector<int> v1;// 这里就是编译器自带的v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);int x;cin >> x;auto it = find(v1.begin(), v1.end(), x);// 删除指定位置的数while (it != v1.end()){v1.erase(it);}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector05(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);v1.push_back(4);v1.push_back(23);v1.push_back(42);v1.push_back(33);v1.push_back(533);v1.push_back(234);v1.push_back(23454);v1.push_back(534534534);for (auto e : v1){cout << e << " ";}cout << endl;// 要求删除所有的偶数auto it = v1.begin();while (it != v1.end()){if (*it % 2 == 0){// erase返回删除位置下一个位置// 失效的迭代器,更新以后再去访问v1.erase(it);}else {it++;}}for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector06(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;// 将v1的size改为20,自动填充0v1.resize(20);for (auto e : v1){cout << e << " ";}cout << endl;// 也可以指定数字。只是已经填充进去的数字无法更改v1.resize(25, 1);for (auto e : v1){cout << e << " ";}cout << endl;v1.resize(2);for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector07(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;vector<int> v2(v1);for (auto e : v2){cout << e << " ";}cout << endl;vector<int> v3{ 1,2,3,4,5 };v1 = v3;for (auto e : v3){cout << e << " ";}cout << endl; for (auto e : v1){cout << e << " ";}cout << endl;}void test_vector08(){vector<int> v1;v1.push_back(1);v1.push_back(2);v1.push_back(3);v1.push_back(4);for (auto e : v1){cout << e << " ";}cout << endl;vector<int> v2(v1.begin(), v1.end());for (auto e : v2){cout << e << " ";}cout << endl;std::string s1("hello world");vector<int> v3(s1.begin(),s1.end());// 打印的是ASSIC码值for (auto e : v3){cout << e << " ";}cout << endl;// 行不通//vector<int> v4(10, 1);//vector<double> v5(10, 1.1);//for (auto e : v4)//{//	cout << e << " ";//}//cout << endl;///*for (auto e : v5)//{//	cout << e << " ";//}//cout << endl;*/}void test_vector09(){vector<string> v1;v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");v1.push_back("1111111111111111");for (auto e : v1){cout << e << " ";}cout << endl;}
}
关键字:安阳门户网站_制作微信小程序步骤_北京seo网站推广_免费十八种禁用网站

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: