😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你------泰戈尔🍭
⏰发布时间⏰:
本文未经允许,不得转发!!!
目录
- 🎄一、概述
- 🎄二、vector复制的方法
-
- [✨2.1 直接拷贝构造](#✨2.1 直接拷贝构造)
- [✨2.2 赋值运算符](#✨2.2 赋值运算符)
- [✨2.3 使用assign()成员函数](#✨2.3 使用assign()成员函数)
- [✨2.4 使用std::copy算法](#✨2.4 使用std::copy算法)
- [✨2.5 使用范围for循环手动复制](#✨2.5 使用范围for循环手动复制)
- [✨2.6 使用std::vector的insert()方法](#✨2.6 使用std::vector的insert()方法)
- [✨2.7 使用C++11的初始化列表](#✨2.7 使用C++11的初始化列表)
- [✨2.8 使用std::vector的swap技巧](#✨2.8 使用std::vector的swap技巧)
- [✨2.9 使用std::copy_n复制特定数量元素](#✨2.9 使用std::copy_n复制特定数量元素)
- 🎄三、综合比较与选择建议
- 🎄四、总结


🎄一、概述
在C++编程中,std::vector是最常用的容器之一。在不同的vector之间复制数据是常见的操作需求。本文将全面介绍C++中从vector复制到另一个vector的各种方法,分析每种方法的优缺点,并提供实际应用场景建议。

🎄二、vector复制的方法
✨2.1 直接拷贝构造
-
优点
语法简洁,直观易读
一次调用完成全部复制
类型安全,编译器会进行类型检查
-
缺点
需要复制整个vector,对于大容器可能效率较低
无法进行部分复制或条件复制
🌰举例:
cpp
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
// 方法1:拷贝构造函数
std::vector<int> vec2(vec1);
// 验证复制结果
for (int num : vec2) {
std::cout << num << " ";
}
// 输出: 1 2 3 4 5
return 0;
}
✨2.2 赋值运算符
-
优点
语法简单,符合直觉
支持链式赋值
可以重用已存在的vector对象
-
缺点
与拷贝构造相同,需要复制全部元素
如果目标vector已有数据,会先销毁原有元素
🌰举例:
cpp
#include <vector>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
std::vector<int> vec2;
// 方法2:赋值运算符
vec2 = vec1;
// 也可以链式赋值
std::vector<int> vec3, vec4;
vec3 = vec4 = vec1;
return 0;
}
✨2.3 使用assign()成员函数
-
优点
灵活,支持多种参数形式
可以清空并替换目标vector的内容
支持范围赋值,可以只复制部分元素
-
缺点
语法相对复杂
会清空目标vector原有内容
🌰举例:
cpp
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
std::vector<int> vec2;
// 方法3:assign()函数
vec2.assign(vec1.begin(), vec1.end());
// assign()也可以接受初始值列表
vec2.assign({1, 2, 3, 4, 5});
// 或者指定数量和值
vec2.assign(5, 100); // 创建5个值为100的元素
std::cout << "vec2大小: " << vec2.size() << std::endl;
return 0;
}
✨2.4 使用std::copy算法
-
优点
高度灵活,可以复制任意范围
可以与其他算法结合使用
可以插入到已有数据后面
-
缺点
需要额外包含头文件
使用back_inserter可能导致多次重新分配内存
语法相对复杂
🌰举例:
cpp
#include <vector>
#include <algorithm> // for std::copy
#include <iterator> // for std::back_inserter
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
std::vector<int> vec2;
// 方法4:std::copy + back_inserter
vec2.reserve(vec1.size()); // 预分配空间以提高效率
std::copy(vec1.begin(), vec1.end(), std::back_inserter(vec2));
// 如果目标vector已有足够空间,可以直接使用
std::vector<int> vec3(5); // 预分配5个元素空间
std::copy(vec1.begin(), vec1.end(), vec3.begin());
// 复制部分元素
std::vector<int> vec4;
std::copy(vec1.begin(), vec1.begin() + 3, std::back_inserter(vec4));
std::cout << "vec4元素: ";
for (int num : vec4) {
std::cout << num << " ";
}
// 输出: 1 2 3
return 0;
}
✨2.5 使用范围for循环手动复制
-
优点
完全控制复制过程
可以添加条件逻辑
便于调试和理解
-
缺点
代码冗长
效率可能不如专用函数
手动管理可能出错
🌰举例:
cpp
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
std::vector<int> vec2;
// 方法5:范围for循环
vec2.reserve(vec1.size()); // 预分配空间
for (const auto& element : vec1) {
vec2.push_back(element);
}
// 带条件复制
std::vector<int> vec3;
for (const auto& element : vec1) {
if (element % 2 == 0) { // 只复制偶数
vec3.push_back(element);
}
}
std::cout << "vec3中的偶数: ";
for (int num : vec3) {
std::cout << num << " ";
}
// 输出: 2 4
return 0;
}
✨2.6 使用std::vector的insert()方法
-
优点
可以插入到任意位置
可以保持目标vector原有数据
支持范围插入
-
缺点
对于简单全复制显得冗余
插入点位置需要小心处理
🌰举例:
cpp
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
std::vector<int> vec2;
// 方法6:insert()方法
vec2.insert(vec2.end(), vec1.begin(), vec1.end());
// 插入到特定位置
std::vector<int> vec3 = {10, 20, 30};
vec3.insert(vec3.begin() + 1, vec1.begin(), vec1.end());
std::cout << "vec3插入后: ";
for (int num : vec3) {
std::cout << num << " ";
}
// 输出: 10 1 2 3 4 5 20 30
return 0;
}
✨2.7 使用C++11的初始化列表
-
优点
语法简洁(C++11及以上)
类型推导方便
一行代码完成构造和复制
-
缺点
仅适用于C++11及以上版本
需要创建新对象,不能复用已有对象
🌰举例:
cpp
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
// 方法7:基于已有vector创建新vector(初始化列表语法)
std::vector<int> vec2 = {vec1.begin(), vec1.end()};
// 或者使用auto简化
auto vec3 = std::vector<int>(vec1.begin(), vec1.end());
std::cout << "vec2大小: " << vec2.size() << std::endl;
std::cout << "vec3大小: " << vec3.size() << std::endl;
return 0;
}
✨2.8 使用std::vector的swap技巧
-
优点
极快的交换操作(O(1)时间复杂度)
不复制元素,只交换内部指针
-
缺点
不是真正的复制,会清空源vector
不适合需要保留源vector的场景
🌰举例:
cpp
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5};
// 方法8:swap技巧(实际上是移动而非复制)
std::vector<int> vec2;
vec2.swap(vec1); // 现在vec2有数据,vec1为空
std::cout << "vec2大小: " << vec2.size() << std::endl;
std::cout << "vec1大小: " << vec1.size() << std::endl;
// 如果确实需要复制,可以结合其他方法
std::vector<int> vec3 = {1, 2, 3, 4, 5};
std::vector<int> vec4(vec3); // 先复制
// 然后可以清空vec3而不影响vec4
return 0;
}
✨2.9 使用std::copy_n复制特定数量元素
-
优点
精确控制复制元素数量
避免边界检查错误
代码意图明确
-
缺点
需要确保源vector有足够元素
需要预分配目标vector空间或使用back_inserter
🌰举例:
cpp
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4, 5, 6, 7, 8};
std::vector<int> vec2;
// 方法9:std::copy_n
vec2.resize(4); // 先调整大小
std::copy_n(vec1.begin(), 4, vec2.begin());
// 或者使用back_inserter
std::vector<int> vec3;
vec3.reserve(3);
std::copy_n(vec1.begin() + 2, 3, std::back_inserter(vec3));
std::cout << "vec3元素: ";
for (int num : vec3) {
std::cout << num << " ";
}
// 输出: 3 4 5
return 0;
}

🎄三、综合比较与选择建议
方法对比表
| 方法 | 适用场景 | 优点 | 缺点 | 性能 |
|---|---|---|---|---|
| 拷贝构造 | 初始化时完整复制 | 简洁、类型安全 | 必须创建新对象 | 高 |
| 赋值运算符 | 替换已有vector内容 | 直观、可链式 | 销毁原有内容 | 高 |
| assign() | 灵活替换内容 | 支持多种参数形式 | 语法较复杂 | 高 |
| std::copy | 部分复制或条件复制 | 高度灵活 | 需额外头文件 | 中高 |
| 范围for | 需要复杂复制逻辑 | 完全控制过程 | 代码冗长 | 中 |
| insert() | 插入到特定位置 | 保持原有数据 | 对全复制冗余 | 中 |
| 初始化列表 | C++11简洁语法 | 代码简洁 | 仅限C++11+ | 高 |
| swap() | 快速转移数据 | 极快(O(1)) |
不是真正复制 | 极高 |
| copy_n() | 精确数量复制 | 控制精确 | 需确保元素足够 | 高 |
选择建议
-
简单完整复制:使用拷贝构造函数或赋值运算符
-
需要清空并替换内容:使用assign()方法
-
部分复制或条件复制:使用std::copy或范围for循环
-
插入到已有数据中:使用insert()方法
-
C++11及以上环境:可以考虑初始化列表语法
-
需要转移所有权而非复制:使用swap()方法
-
性能敏感场景:使用拷贝构造/赋值并预分配空间

🎄四、总结
C++提供了多种从vector复制到另一个vector的方法,每种方法都有其适用场景。选择合适的方法需要考虑:
-
是否需要完整复制还是部分复制
-
是否需要条件筛选
-
性能要求
-
代码可读性
-
C++版本兼容性
在大多数情况下,对于简单完整的复制,拷贝构造函数和赋值运算符是最佳选择,它们简洁高效。对于更复杂的复制需求,std::copy系列算法和assign()方法提供了更大的灵活性。记住,在复制大型vector时,预分配空间可以显著提高性能。

如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁