当前位置: 首页 > news >正文

vector

💬 :如果你在阅读过程中有任何疑问或想要进一步探讨的内容,欢迎在评论区畅所欲言!我们一起学习、共同成长~!

👍 :如果你觉得这篇文章还不错,不妨顺手点个赞、加入收藏,并分享给更多的朋友噢~!


1. vector 的基本介绍

基本定义

  • vector 是表示可变大小数组的序列容器。

存储特性

  • 就像数组一样,vector 也采用连续存储空间来存储元素,意味着可以采用下标对 vector 的元素进行访问,和数组一样高效。

扩容机制

  • 当新元素插入时,若原数组空间不足,需要重新分配大小以增加存储空间。其做法是分配一个新数组,并将全部元素移到新数组。

空间策略

  • vector 会分配一些额外的空间以适应可能的增长,不同的库采用不同的策略来权衡空间的使用和重新分配,但重新分配都应是对数增长的间隔大小,以保证在末尾插入一个元素时是在常数时间复杂度完成的。

性能权衡

  • vector 占用了更多的存储空间,以换取管理存储空间的能力,并且能够以一种有效的方式动态增长。

容器对比

  • 与 deque、list 和 forward_list 等其他动态序列容器相比,vector 在访问元素时更加高效,在末尾添加和删除元素相对高效,但对于不在末尾的删除和插入操作,效率较低。与 list 和 forward_list 相比,vector 具有统一的迭代器和引用。


2. vector 的基本操作与使用

2.1 构造函数

构造函数声明接口说明
vector<类型> vec;(重点)无参构造
vector<类型> vec(n, val);构造并初始化 n 个 val
vector<类型> vec2(vec1);(重点)拷贝构造
vector<类型> vec(起始迭代器, 结束迭代器);使用迭代器进行初始化构造

2.1.1 vector<类型> vec;(重点)

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec; // 通过无参构造创建一个空的向量cout << "Size of vec: " << vec.size() << endl; return 0;
}

2.1.2 vector<类型> vec(n, val);

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec1(5, 10); // 创建一个包含5个元素的向量,所有元素初始化为10vector<int> vec2(3);     // 创建一个包含3个元素的向量,默认初始化为0for (int i : vec1) {cout << i << " ";}cout << endl;for (int i : vec2) {cout << i << " ";}cout << endl;return 0;
}

2.1.3 vector<类型> vec2(vec1);(重点)

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec1 = { 1, 2, 3, 4, 5 };vector<int> vec2(vec1); for (int i : vec2) {cout << i << " ";}cout << endl;return 0;
}

2.1.4 vector<类型> vec(起始迭代器, 结束迭代器);

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec1 = { 1, 2, 3, 4, 5 };vector<int> vec(vec1.begin(), vec1.end());// 或者用数组// int arr[] = { 1, 3, 5, 7, 9 };// vector<int> vec(arr, arr + sizeof(arr) / sizeof(arr[0]));for (int i : vec) {cout << i << " ";}cout << endl;return 0;
}

2.2 迭代器(iterator)操作

begin()(重点)指向容器第一个元素的正向迭代器(const版本返回常量迭代器)
end()(重点)指向容器最后一个元素的下一个位置的正向迭代器(常作为循环终止条件)
rbegin()指向容器最后一个元素的反向迭代器(用于逆序遍历)
rend()指向容器第一个元素的前一个位置的反向迭代器(逆序遍历终止条件)
#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec = { 10, 20, 30, 40, 50 };cout << "正向遍历:";for (auto it = vec.begin(); it != vec.end(); ++it) {cout << *it << " ";}cout << std::endl;cout << "逆序遍历:";for (auto it = vec.rbegin(); it != vec.rend(); ++it) {cout << *it << " ";}cout << endl;return 0;
}

2.3 容量操作

size()

获取当前 vector 中元素的数量。

capacity()

获取分配给 vector 的存储空间大小。

empty()

判断 vector 是否为空。若 vector 中没有元素,返回 true;否则返回 false

(1)resize(n)(重点)

调整有效元素数量size()至n。

  • 若 n > 原size() :在 vector 末尾添加新元素,(1)新添元素调用默认构造函数初始化;(2)新添元素指定初始化为val 。

  • 若 n < 原size() :销毁多余元素(调用析构函数)。

(2)resize(n,val)(重点)
reserve(n)(重点)

预先为 vector 分配至少 n 个元素所需的存储空间。

  • 如果 n > 当前容量,则分配新内存空间,使capacity()至少达到 n,但不改变现有元素的size()或内容。这可以避免后续添加元素时频繁重新分配内存。

  • 如果 n <= 当前容量,则不会进行任何操作。

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec = { 1, 2, 3 };cout << "(1)" << endl;cout << "当前元素数量: " << vec.size() << endl;cout << "当前容量: " << vec.capacity() << endl;cout << "vector 是否为空? " << (vec.empty() ? "是" : "否") << endl;// resize() 扩大 vector 的大小vec.resize(5, 10); cout << "(2)" << endl;cout << "大小调整为 5,新元素为 10 后:\n";cout << "新大小: " << vec.size() << endl;cout << "新容量: " << vec.capacity() << endl;cout << "元素: ";for (int val : vec) {cout << val << " ";}cout << endl;// resize() 缩小 vector 的大小vec.resize(3); cout << "(3)" << endl;cout << "大小调整为 3 后:\n";cout << "新大小: " << vec.size() << endl;cout << "当前容量: " << vec.capacity() << endl;cout << "元素: ";for (int val : vec) {cout << val << " ";}cout << endl;vec.reserve(10); cout << "(4)" << endl;cout << "预分配容量为 10 个元素后:\n";cout << "当前大小: " << vec.size() << endl;cout << "新容量: " << vec.capacity() << endl;// 添加新元素,观察内存分配行为vec.push_back(20); // 添加一个新元素cout << "(5)" << endl;cout << "添加一个元素后:\n";cout << "当前大小: " << vec.size() << endl;cout << "当前容量: " << vec.capacity() << endl;cout << "元素: ";for (int val : vec) {cout << val << " ";}cout << endl;return 0;
}

2.4 修改操作

push_back(val)(重点)vector 的末尾添加一个元素 val ,可能触发扩容。
pop_back()(重点)删除 vector 的最后一个元素。
find()
  • 在指定范围内查找第一个等于目标值的元素,找到后返回指向该元素的迭代器;否则返回 end()
  • 使用时需包含 <algorithm> 头文件
  • std::find() 是通用算法,适用于所有支持迭代器的容器,而非 vector 专属。
insert(指定位置的迭代器,插入值)在指定位置插入一个元素,可能触发扩容。
erase(指定位置的迭代器/区间)删除指定位置/指定区间的元素。删除后,后面的元素会向前移动一个位置。
swap(另一个 vector 对象)交换两个 vector 的内容。
operator[索引](重点)像数组一样通过索引访问和修改元素,不检查越界。

2.4.1 push_back() + pop_back()

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec = { 1, 2, 3 };vec.push_back(4); vec.push_back(5); cout << "尾插后元素:";for (int val : vec) {cout << val << " ";}cout << endl;vec.pop_back();cout << "尾删后元素:";for (int val : vec){cout << val << " ";}cout << endl;return 0;
}

2.4.2 find()

#include <iostream>
#include <vector>
#include <algorithm> 
using namespace std;int main() 
{vector<int> vec = { 1, 2, 3, 4, 5 };auto it = find(vec.begin(), vec.end(), 3);if (it != vec.end()) {cout << "找到元素: " << *it << " ,位置: " << distance(vec.begin(), it) << endl;}else {cout << "未找到元素" << endl;}return 0;
}

2.4.3 insert() + erase()

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec = { 1, 2, 4, 5 };cout << "初始元素:";for (int val : vec){cout << val << " ";}cout << endl;vec.insert(vec.begin() + 2, 3); cout << "指定位置插值后元素:";for (int val : vec) {cout << val << " ";}cout << endl;vec.erase(vec.begin() + 1);cout << "指定位置删值后元素:";for (int val : vec){cout << val << " ";}cout << endl;return 0;
}

2.4.4 swap()

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec1 = { 1, 2, 3 };vector<int> vec2 = { 4, 5, 6 };vec1.swap(vec2); cout << "vec1 after swap: ";for (int val : vec1) {cout << val << " ";}cout << endl;cout << "vec2 after swap: ";for (int val : vec2) {cout << val << " ";}cout << endl;return 0;
}

2.4.5 operator[]

#include <iostream>
#include <vector>
using namespace std;int main() 
{vector<int> vec = { 10, 20, 30, 40, 50 };cout << "Element at index 2: " << vec[2] << endl; // 访问索引为 2 的元素vec[2] = 300; // 修改索引为 2 的元素cout << "Elements after modification: ";for (int val : vec) {cout << val << " ";}cout << endl;return 0;
}


3. vector 迭代器失效问题(重点)

3.1 迭代器失效简单介绍

  • 迭代器的本质与作用

    • 本质:底层为指针或指针封装(如vector迭代器即原生指针T*)。
    • 作用:使算法与底层数据结构解耦,实现通用逻辑。
  • 迭代器失效的定义

    • 核心:迭代器指向的内存空间被销毁或无效化。
    • 表现:底层指针指向已释放 / 重新分配的内存。
  • 失效的后果

    • 直接风险:访问无效内存导致程序崩溃(未定义行为)。
    • 逻辑隐患:操作失效迭代器可能引发数据破坏或运行时错误。

3.2 迭代器失效场景总结

操作类型具体操作失效原因示例代码平台差异
引起底层空间改变resize触发内存重新分配,原指针指向的旧内存被释放
vector<int> v = {1,2,3};
auto it = v.begin();
v.resize(10);
// it 失效
VS:使用失效迭代器直接崩溃
g++:可能不报错但结果异常
reserve
insert插入元素导致扩容时,原内存被释放
v.push_back(4);
// 若触发扩容,所有迭代器失效
同上
push_back
assign覆盖原有元素可能触发扩容
v.assign(10, 0);
// 若新容量超过原capacity,迭代器失效
同上
删除指定位置元素erase(pos)元素前移导致pos及之后的迭代器失效;若删除最后元素,pos变为end()
auto it = v.begin() + 1;
v.erase(it);
// it 及之后迭代器失效

VS:直接标记pos失效
g++:可能允许访问pos-1位置
特殊场景删除最后元素erase(end()-1) 后,end() 迭代器失效
v.erase(v.end()-1);
// 此时 v.end() 已失效

VS:访问end()立即崩溃
g++:可能不报错但结果异常
与 vector 类似的容器string 操作插入、扩容、erase 操作后迭代器失效机制与vector完全相同
string s = "abc";
auto it = s.begin();
s += "d";
// it 可能失效

VS / g++:处理方式与vector一致

VS (MSVC)
  • 严格遵循标准,对失效迭代器立即报错(如解引用时触发断言)
  • 插入 / 删除后强制标记相关迭代器为无效状态
g++ (SGI)
  • 仅做宽松检查,可能允许访问已失效但未被覆盖的内存区域
  • 运行结果可能异常但不崩溃(依赖内存状态)

3.3 迭代器失效解决办法

核心逻辑:容器状态变更后,迭代器需重新指向当前有效内存,确保每次使用前均为最新有效值。

  • 操作后实时更新:插入 / 删除等操作后,立即通过 begin()/end() 重新获取迭代器,确保指向有效位置。
  • 循环删除场景:利用 erase 返回值更新迭代器(it = v.erase(it)),避免跳过元素或访问失效位置。
  • 禁止缓存迭代器:避免在操作前保存迭代器,改为操作后按需实时获取。
  • 防御性编程原则:假设所有容器操作均可能导致迭代器失效,使用前重新赋值迭代器(通用跨平台方案)。


4. vector 的应用

4.1 只出现一次的数字 I

只出现一次的数字

#include <iostream>
#include <vector>
using namespace std;class Solution 
{
public:int singleNumber(vector<int>& nums) {int value = 0;for (auto e : nums) {  value ^= e;       // 异或操作:value = value ^ e}return value;        }
};int main() 
{Solution sol;vector<int> nums = { 4, 1, 2, 1, 2 };  cout << "只出现一次的元素:" << sol.singleNumber(nums) << endl;return 0;
}

4.2 杨辉三角

杨辉三角

#include <iostream>
#include <vector>
using namespace std;class Solution 
{
public:vector<vector<int>> generate(int numRows) {vector<vector<int>> vv(numRows); // 初始化一个包含numRows行的二维向量// 填充每行的首尾元素为1,并初始化每行长度for (int i = 0; i < numRows; ++i) {vv[i].resize(i + 1, 1); // 第i行有i+1个元素,全部初始化为1}// 计算中间元素(从第3行开始,索引从2开始)for (int i = 2; i < numRows; ++i) { // i表示当前行号(从0开始,第2行对应i=2)for (int j = 1; j < i; ++j) { // j表示当前行的列号(从1开始,避开首尾的1)// 当前元素等于上一行同一列和前一列元素之和vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];}}return vv; }
};int main() 
{Solution sol;int numRows = 5; vector<vector<int>> result = sol.generate(numRows); cout << "杨辉三角前 " << numRows << " 行:" << endl;for (const auto& row : result) { // 遍历每一行for (int num : row) { // 遍历每行的元素cout << num << " ";}cout << endl; }return 0;
}

4.3 删除有序数组中的重复项

删除有序数组中的重复项

#include <iostream>
#include <vector>
using namespace std;int removeDuplicates(vector<int>& nums) 
{if (nums.empty()) return 0;int k = 1;for (int i = 1; i < nums.size(); i++) {if (nums[i] != nums[i - 1]) {nums[k] = nums[i];k++;}}return k;
}int main() 
{vector<int> nums = { 0,0,1,1,1,2,2,3,3,4 };cout << "Original array: ";for (int num : nums) {cout << num << " ";}cout << endl;int k = removeDuplicates(nums);cout << "New length: " << k << endl;cout << "Modified array: ";for (int i = 0; i < k; i++) {cout << nums[i] << " ";}cout << endl;return 0;
}

4.4 只出现一次的数字 II

只出现一次的数字 II

#include <iostream>
#include <vector>
using namespace std;int singleNumber(vector<int>& nums) 
{int ones = 0, twos = 0;for (int num : nums) {ones = (ones ^ num) & ~twos;twos = (twos ^ num) & ~ones;}return ones;
}int main() 
{vector<int> nums = { 0, 1, 0, 1, 0, 1, 99 };cout << "Input array: ";for (int num : nums) {cout << num << " ";}cout << endl;int result = singleNumber(nums);cout << "The single number is: " << result << endl;return 0;
}

4.5 只出现一次的数字 III

只出现一次的数字 III

#include <iostream>
#include <vector>
using namespace std;vector<int> singleNumber(vector<int>& nums) 
{long long xor_all = 0;for (int num : nums) {xor_all ^= num;}long long diff_bit = xor_all & -xor_all;int a = 0, b = 0;for (int num : nums) {if (num & diff_bit) {a ^= num;}else {b ^= num;}}return { a, b };
}int main() 
{vector<int> nums = { 1, 2, 1, 3, 2, 5 };cout << "Input array: ";for (int num : nums) {cout << num << " ";}cout << endl;vector<int> result = singleNumber(nums);cout << "The two single numbers are: " << result[0] << " and " << result[1] << endl;return 0;
}

4.6 数组中出现次数超过一半的数字

数组中出现次数超过一半的数字

#include <iostream>
#include <vector>
using namespace std;int MoreThanHalfNum_Solution(vector<int> numbers) 
{int candidate = numbers[0];int count = 1;for (int i = 1; i < numbers.size(); i++) {if (numbers[i] == candidate) {count++;}else {count--;if (count == 0) {candidate = numbers[i];count = 1;}}}return candidate;
}int main() 
{vector<int> numbers = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };cout << "Input array: ";for (int num : numbers) {cout << num << " ";}cout << endl;int result = MoreThanHalfNum_Solution(numbers);cout << "The majority element is: " << result << endl;return 0;
}

4.7 电话号码的字母组合

电话号码的字母组合

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;class Solution 
{
public:vector<string> letterCombinations(string digits) {if (digits.empty()) return {};unordered_map<char, string> phoneMap{{'2', "abc"},{'3', "def"},{'4', "ghi"},{'5', "jkl"},{'6', "mno"},{'7', "pqrs"},{'8', "tuv"},{'9', "wxyz"}};vector<string> result;string current;backtrack(digits, 0, phoneMap, current, result);return result;}private:void backtrack(const string& digits, int index,const unordered_map<char, string>& phoneMap,string& current, vector<string>& result) {if (index == digits.size()) {result.push_back(current);return;}char digit = digits[index];string letters = phoneMap.at(digit);for (char c : letters) {current.push_back(c);backtrack(digits, index + 1, phoneMap, current, result);current.pop_back();}}
};int main() 
{Solution sol;string digits = "23";cout << "Input digits: " << digits << endl;cout << "Letter combinations: [";vector<string> combinations = sol.letterCombinations(digits);for (int i = 0; i < combinations.size(); i++) {cout << "\"" << combinations[i] << "\"";if (i != combinations.size() - 1) {cout << ", ";}}cout << "]" << endl;return 0;
}


5. vector 的深度剖析及模拟实现

5.1 底层结构剖析

5.1.1 数据结构本质

  • 动态数组实现:基于原生指针 T* _data 管理连续内存空间。
  • 三要素成员变量:

    size_t _size;    // 当前有效元素个数
    size_t _capacity; // 总分配内存容量(元素个数)
    T* _data;        // 指向内存首地址的指针
    
  • 内存布局特点:
    • 物理空间连续,支持随机访问(符合数组特性)。
    • 逻辑空间(_size)≤ 物理空间(_capacity)。

5.1.2 空间管理

5.1.2.1 扩容机制核心逻辑

当 _size == _capacity 时触发扩容。流程如下:

  1. 计算新容量(通常为原容量的2倍)

  2. 分配新内存

  3. 迁移原有数据至新内存

  4. 释放旧内存

  5. 更新指针与容量信息

5.1.2.2 扩容函数实现
void reserve(size_t new_cap) 
{if (new_cap <= _capacity) return; // 无需扩容T* new_data = new T[new_cap];     // 分配新内存std::move(_data, _data + _size, new_data); // 移动元素(C++11后优先用move)delete[] _data;                   // 释放旧内存_data = new_data;_capacity = new_cap;
}

5.1.2.3 扩容代价
  • 时间:O (n) 元素拷贝(原始数据量较大时性能开销显著)。
  • 空间:预分配策略导致内存利用率可能低于 100%。

5.2 模拟实现中的拷贝问题

使用 memcpy 拷贝的隐患

memcpy 是 C/C++ 标准库中用于内存复制的函数,将一段内存空间中内容原封不动地拷贝到另外一段内存空间中。

memcpy 的拷贝是浅拷贝。

用生活里的例子来理解浅拷贝:

假设你有个盒子(vector),专门装“租房合同”(自定义类型)—— 上面写着你租的房子的地址(指针指向动态内存)。

有一天盒子装不下了,你要换个更大的盒子(reserve 扩容)。这时如果直接原样复印(memcpy 二进制拷贝)旧盒子里的 “租房合同” 放到到新盒子里,新、旧盒子的 “租房合同” 指向相同的旧房子。

但旧盒子扔掉了(释放旧空间),旧房子也退租了(内存被释放)。这时新盒子里的 “租房合同” 就成了 “无效合同”(野指针)—— 再按上面的地址去 “租房子”(访问内存)就会出问题(程序崩溃),甚至可能因为没正确退租(内存没释放)导致后续麻烦(内存泄漏)。

  • 总结:如果装的东西是 “租房合同” 这种需要自己管房子(资源管理)的类型,千万别直接复印 “租房合同”(memcpy 浅拷贝),得写一份新的 “租房合同”(深拷贝,复制房子本身)。

模拟实现 vector 的 reserve 接口时,若使用 memcpy 进行拷贝:

  • 内置类型拷贝有效且高效

  • 自定义类型拷贝可能导致:

    1. 浅拷贝问题(多个对象共享同一资源)

    2. 内存泄漏(原对象释放资源后,拷贝对象悬空)

    3. 双重释放(多个对象尝试释放同一资源)

正确实现: 使用深拷贝逐个构造元素,确保每个对象独立管理资源。

5.3 

5.3.1 模拟实现步骤                                                                                                  

5.3.1.1 类模板定义
template <typename T>
class vector {
private:T* _data;size_t _size;size_t _capacity;public:// 构造/析构/赋值vector();~vector();vector(const vector&);vector& operator=(const vector&);vector(vector&&) noexcept;vector& operator=(vector&&) noexcept;// 迭代器T* begin();T* end();// 容量操作size_t size() const;size_t capacity() const;void reserve(size_t);void resize(size_t);void resize(size_t, const T&);// 元素操作void push_back(const T&);void pop_back();T& operator[](size_t);
};
5.3.1.2 push_back 实现(含扩容逻辑)
void push_back(const T& val) {if (_size == _capacity) { // 触发扩容size_t new_cap = _capacity == 0 ? 1 : _capacity * 2;reserve(new_cap);}_data[_size++] = val; 
}
5.3.1.3 insert 实现(处理迭代器失效)
iterator insert(iterator pos, const T& val) {size_t idx = pos - begin(); // 计算插入位置索引if (_size == _capacity) {size_t new_cap = _capacity == 0 ? 1 : _capacity * 2;reserve(new_cap);pos = begin() + idx; // 扩容后迭代器需重新定位}// 元素后移std::move_backward(pos, end(), end() + 1);_data[idx] = val;_size++;return pos; // 返回新插入位置的迭代器
}

5.3.1.4 拷贝构造实现(深拷贝)
vector(const vector& rhs) {_data = new T[rhs._capacity];_capacity = rhs._capacity;_size = rhs._size;std::copy(rhs._data, rhs._data + _size, _data);
}

5.3.1.5 拷贝赋值运算符实现(三步复制-交换法则)
vector& operator=(const vector& rhs) {if (this != &rhs) {T* new_data = new T[rhs._capacity];std::copy(rhs._data, rhs._data + rhs._size, new_data);delete[] _data;_data = new_data;_size = rhs._size;_capacity = rhs._capacity;}return *this;
}

5.3.2 完整模拟实现

#include <cstddef> // 为了使用 size_t
#include <algorithm> // 为了使用 std::move_backward 和 std::copytemplate <typename T>
class vector {
private:T* _data;       size_t _size;   size_t _capacity; public:vector() : _data(nullptr), _size(0), _capacity(0) {}~vector() {delete[] _data;}vector(const vector& rhs) {_data = new T[rhs._capacity];_capacity = rhs._capacity;_size = rhs._size;std::copy(rhs._data, rhs._data + rhs._size, _data); // 复制元素}// 拷贝赋值运算符vector& operator=(const vector& rhs) {if (this != &rhs) { T* new_data = new T[rhs._capacity];std::copy(rhs._data, rhs._data + rhs._size, new_data); // 复制数据delete[] _data; _data = new_data;_size = rhs._size;_capacity = rhs._capacity;}return *this;}// 迭代器T* begin() { return _data; } // 返回起始迭代器T* end() { return _data + _size; } // 返回结束迭代器// 容量操作size_t size() const { return _size; } // 返回当前元素数量size_t capacity() const { return _capacity; } // 返回总容量// 预分配内存(仅分配内存,不改变大小)void reserve(size_t new_cap) {if (new_cap <= _capacity) return; // 如果新容量不大于当前容量,则无需操作T* new_data = new T[new_cap];std::move(_data, _data + _size, new_data); // 移动元素到新内存delete[] _data; // 释放旧内存_data = new_data;_capacity = new_cap;}// 调整向量大小(调整有效元素数量)void 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) {new (_data + i) T(); // 使用 placement new 构造元素}} else {// 销毁多余元素for (size_t i = new_size; i < _size; ++i) {_data[i].~T(); // 显式调用析构函数}}_size = new_size;}// 带值初始化调整大小void resize(size_t new_size, const T& value) {if (new_size > _capacity) {reserve(new_size);}if (new_size > _size) {// 用给定值构造新元素for (size_t i = _size; i < new_size; ++i) {new (_data + i) T(value); // 带值的 placement new}} else {// 销毁多余元素for (size_t i = new_size; i < _size; ++i) {_data[i].~T();}}_size = new_size;}// 元素操作void push_back(const T& val) {if (_size == _capacity) { // 如果当前容量已满size_t new_cap = _capacity == 0 ? 1 : _capacity * 2; // 计算新容量reserve(new_cap); // 触发扩容}// 使用 placement new 构造元素new (_data + _size) T(val);++_size; // 更新大小}void pop_back() {if (_size > 0) { // 如果有元素--_size; // 减少大小_data[_size].~T(); // 显式销毁最后一个元素}}T& operator[](size_t index) {return _data[index]; // 返回指定索引的元素引用}// 在位置 pos 插入元素typename vector<T>::iterator insert(iterator pos, const T& val) {size_t idx = pos - begin(); // 计算插入位置的索引if (_size == _capacity) { // 如果需要扩容size_t new_cap = _capacity == 0 ? 1 : _capacity * 2;reserve(new_cap); // 执行扩容pos = begin() + idx; // 重新定位迭代器}// 向右移动元素,腾出空间std::move_backward(pos, end(), end() + 1);// 在位置 idx 构造新元素new (_data + idx) T(val);++_size; // 更新大小return pos; // 返回新元素的位置}
};

相关文章:

  • unittest
  • 腾讯2025年校招笔试真题手撕(一)
  • 嵌入式学习笔记 - 关于ARM编辑器compiler version 5 and compiler version 6
  • Facebook广告如何投放保健品类别?
  • 徐少春迎来AI的春天
  • Zephyr OS 中的互斥信号量
  • 网络安全-等级保护(等保) 3-1-1 GB/T 28448-2019 附录A (资料性附录)测评力度附录C(规范性附录)测评单元编号说明
  • NSSCTF-[陇剑杯 2021]webshell(问6)
  • 笔记本6GB本地可跑的图生视频项目(FramePack)
  • 2025年- H41-Lc149 --138. 随机链表的复制(链表,哈希)-(需二刷)--Java版
  • mingw下使用msvc的onnxruntime库
  • 某数官网 点选验证
  • 《C 语言字符串操作从入门到实战(下篇):strncpy/strncat/strstr 等函数原理与实现》
  • (初级)前端初学者入门指南:HTML5与CSS3核心知识详解
  • 安卓手机安装 ChatGPT 全流程图文指南
  • KaihongOS设备开发中Sensor 驱动开发
  • 【ffmpeg】硬软编码
  • 深入理解Diffusers: 从基础到Stable Diffusion
  • Tomcat多实例配置
  • AttributeError: module ‘cv2.dnn‘ has no attribute ‘DictValue‘错误解决方法
  • 一元购网站建设流程/seo自学网免费
  • 焦作建网站/东莞排名优化团队
  • wordpress slider 插件/家庭优化大师免费下载
  • xp做的网站有连接限制/电商网站推广方案
  • 做一个网站的策划方案/策划方案怎么做
  • 男人与女人做视频网站/搜索引擎优化seo方案