【C++ | STL】std::vector 复制的几个方法总结

😁博客主页😁:🚀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时,预分配空间可以显著提高性能。

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

相关推荐
惺忪97981 小时前
Qt C++11/14/17 新特性大全详解
开发语言·c++
Pacify_The_North1 小时前
【C++11(二)】可变参数模板和 lambda表达式
java·开发语言·c++
顺顺 尼2 小时前
包装器c++11
开发语言·c++
獭.獭.2 小时前
C++ -- 二叉搜索树
数据结构·c++·算法·二叉搜索树
charlie1145141912 小时前
深入理解CC++的编译与链接技术8:Windows和Linux是如何搜寻动态库的?
c语言·c++·动态库·编译·编译技术
郝学胜-神的一滴2 小时前
Linux信号四要素详解:从理论到实践
linux·服务器·开发语言·网络·c++·程序人生
yangpipi-2 小时前
《C++并发编程实战》 第3章 在线程间共享数据
开发语言·c++
fish_xk2 小时前
c++基础
开发语言·c++
互亿无线明明2 小时前
如何为全球业务构建可扩展的“群发国际短信接口”?
java·c++·python·golang·eclipse·php·erlang