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等没有任何优化作用,还是会拷贝,因为它们实现没有对应的移动构造函数)

相关推荐
虾球xz9 分钟前
游戏引擎学习第267天:为每个元素添加裁剪矩形
c++·学习·游戏引擎
Dovis(誓平步青云)1 小时前
解构C++高级命名空间:构建空间作用域·控制兼容
开发语言·c++·经验分享·笔记·学习方法
Tummer83631 小时前
C语言与C++的区别
c语言·c++·算法
2301_807611492 小时前
47. 全排列 II
c++·算法·leetcode·回溯
✿ ༺ ོIT技术༻2 小时前
笔试强训:Day4
c++·算法
老歌老听老掉牙3 小时前
Open CASCADE学习|实现裁剪操作
c++·学习·opencascade·裁剪
姜行运3 小时前
数据结构【二叉搜索树(BST)】
android·数据结构·c++·c#
技术求索者7 小时前
c++学习
开发语言·c++·学习
左直拳11 小时前
c++中“&”符号代表引用还是取内存地址?
开发语言·c++·指针·引用·右值·取内存地址
十年编程老舅11 小时前
二本计算机,毕业=失业?
c++·程序员·编程·秋招·c++项目·春招·qt项目