博客主页:https://blog.csdn.net/wkd_007
博客内容:嵌入式开发、Linux、C语言、C++、数据结构、音视频
本文内容:介绍
金句分享:你不能选择最好的,但最好的会来选择你——泰戈尔
⏰发布时间⏰:

本文未经允许,不得转发!!!


在这里插入图片描述
在这里插入图片描述

一、概述

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

在这里插入图片描述

二、vector复制的方法

✨2.1 直接拷贝构造

  • 优点
    语法简洁,直观易读
    一次调用完成全部复制
    类型安全,编译器会进行类型检查

  • 缺点
    需要复制整个vector,对于大容器可能效率较低
    无法进行部分复制或条件复制

举例:

#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已有数据,会先销毁原有元素

举例:

#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原有内容

举例:

#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可能导致多次重新分配内存
    语法相对复杂

举例:

#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循环手动复制

  • 优点
    完全控制复制过程
    可以添加条件逻辑
    便于调试和理解

  • 缺点
    代码冗长
    效率可能不如专用函数
    手动管理可能出错

举例:

#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原有数据
    支持范围插入

  • 缺点
    对于简单全复制显得冗余
    插入点位置需要小心处理

举例:

#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及以上版本
    需要创建新对象,不能复用已有对象

举例:

#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的场景

举例:

#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

举例:

#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时,预分配空间可以显著提高性能。

在这里插入图片描述
如果文章有帮助的话,点赞、收藏⭐,支持一波,谢谢