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

相关推荐
晚风吹红霞4 小时前
C++异常处理核心知识点全解析
开发语言·c++
CoderCodingNo4 小时前
【信奥业余科普】C++ 的奇妙之旅 | 17:面的铺展与文本的本质——二维数组与字符串
开发语言·c++
迷途之人不知返5 小时前
优先级队列:priority_queue
数据结构·c++
曦夜日长5 小时前
C++ STL容器string(一):string的变量细节、默认函数的认识以及常用接口的使用
java·开发语言·c++
代码中介商5 小时前
C++ STL 标准模板库完全指南:从容器到迭代器
开发语言·c++·stl
winner88815 小时前
C++ 构造函数、析构函数、虚函数、虚析构
开发语言·c++
想唱rap5 小时前
应用层协议与序列化
linux·运维·服务器·网络·数据结构·c++·算法
许长安5 小时前
protobuf 使用详解
c++·经验分享·笔记·中间件
Soley5 小时前
用 Boost.Log 封装一个更顺手的 C++17 日志库:GoodLog
c++
HAPPY酷5 小时前
从Public到Private:UE5 C++类创建路径差异全解析
java·c++·ue5