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

相关推荐
凯子坚持 c5 分钟前
Redis核心通用命令深度解析:结合C++ redis-plus-plus 实战指南
c++·redis·log4j
神里流~霜灭27 分钟前
(C++)数据结构初阶(顺序表的实现)
linux·c语言·数据结构·c++·算法·顺序表·单链表
John_ToDebug36 分钟前
从源码视角全面解析 Chrome UI 布局系统及 Views 框架的定制化实现方法与实践经验
c++·chrome·架构
愚润求学1 小时前
【贪心算法】day7
c++·算法·leetcode·贪心算法
深耕AI1 小时前
【MFC简介:从基础概念到实际应用】
c++·mfc
六点半8881 小时前
【C++】C++11 篇二
开发语言·c++
DDDDDDDRDDR1 小时前
C++容器:list
开发语言·c++·stl
一拳一个呆瓜1 小时前
【MFC】对话框属性:Use System Font(使用系统字体)
c++·mfc
Elnaij1 小时前
从C++开始的编程生活(7)——取地址运算符重载、类型转换、static成员和友元
开发语言·c++
郝学胜-神的一滴2 小时前
Effective Modern C++ 条款26:避免在通用引用上重载
开发语言·c++·程序人生