20、移动语义有什么作用,原理是什么【中高频】

  • 移动语义的的本质其实也是复制,但是和普通的拷贝复制不同。对于 动态分配的内存 和其他大型的资源,拷贝的话 开销会很大 。而移动语义就是 让对象的资源被移动 到新对象,而不是去拷贝,从而节省资源和时间。

  • 移动语义 通过 移动构造函数 和 移动赋值运算符 实现。源对象的资源 被转移到目标对象,源对象变为无效状态。

cpp 复制代码
  #include <iostream>  
  #include <vector>  
   
  class MyVector {  
  public:  
      MyVector(size_t size) : data(new int[size]), size(size) {  
          std::cout << "Constructing MyVector of size " << size << std::endl;  
      }  
      
      // 移动构造函数  
      MyVector(MyVector&& other) noexcept : data(other.data), size(other.size) {  
          other.data = nullptr;  // 将原对象的指针设为空  
          other.size = 0;  
          std::cout << "Moving MyVector of size " << size << std::endl;  
      }  
   
      // 移动赋值运算符  
      MyVector& operator=(MyVector&& other) noexcept {  
          if (this != &other) {  
              delete[] data;  // 释放当前对象的内存  
              data = other.data; // 移动资源  
              size = other.size;  
              other.data = nullptr; // 将原对象的指针设为空  
              other.size = 0;  
              std::cout << "Moving assignment of MyVector of size " << size << std::endl;  
          }  
          return *this;  
      }  
      
      ~MyVector() {  
          delete[] data; // 释放资源  
          std::cout << "Destroying MyVector" << std::endl;  
      }  
   
  private:  
      int* data;  
      size_t size;  
  };  
   
  int main() {  
      MyVector vec1(10);         // 构造一个对象  
      MyVector vec2 = std::move(vec1); // 移动构造  
      MyVector vec3(5);  
      vec3 = std::move(vec2);   // 移动赋值  
      
      return 0;  
  }
  • 移动语义:通过移动构造函数来实现。
cpp 复制代码
  class A {
  public:
      A(int size) : size_(size) {
          data_ = new int[size];
      }
      
      A(){}
      
      A(const A& a) {
          size_ = a.size_;
          data_ = new int[size_];
          cout << "copy " << endl;
      }
      
      A(A&& a) { //移动资源不是自动实现的,而是我们程序员自己在移动构造函数里写出来的逻辑
          this->data_ = a.data_;
          a.data_ = nullptr;
          cout << "move " << endl;
      }
      
      ~A() {
          if (data_ != nullptr) {
           delete[] data_;
          }azs
      }
      
      int *data_;
      int size_;
  };
  int main() {
      A a(10);
      A b = a;
      A c = std::move(a); // 调用移动构造函数(把对象改为右值后,就会调用移动构造函数了)
      return 0;
  }
  • 使用移动语义可以避免很多无用的拷贝,提供程序性能,C++所有的STL都实现了移动语义,方便我们使用:
cpp 复制代码
  std::vector<string> vecs;
  ...
  std::vector<string> vecm = std::move(vecs); // 免去很多拷贝

(注意:移动语义仅针对于那些实现了移动构造函数的类的对象,对于那种基本类型int、float等没有任何优化作用,还是会拷贝,因为它们实现没有对应的移动构造函数)

相关推荐
倒头就睡的小比特2 天前
算法竞赛C++常用的STL
c++·算法
weilx12343 天前
C++笔记-文件IO-<fcntl.h>
c++
Smileyqp沛沛3 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车3 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
吞下星星的少年·-·3 天前
C++ 萌新语法入门篇
c++·算法比赛
霍霍的袁3 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
程序猿编码3 天前
告别改源码适配模型:纯 C++ 可配置 LLM 推理引擎,全格式全结构兼容
c++·大模型·llm·推理引擎
此生决int3 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++