当前位置: 首页 > news >正文

C++ 11 中的move赋值运算符

C++ 11 中的move赋值运算符

移动赋值是一种将资源(如内存、文件等)从一个对象转移到另一个对象而不复制它们的方法。
例子:

#include <iostream>
#include <vector>
// for std::move
#include <utility> int main() {std::vector<int> a = {1, 2, 3, 4};std::vector<int> b;// move assignment!b = std::move(a);  // a is now emptystd::cout << "a.size() = " << a.size() << "\n";// b has the datastd::cout << "b.size() = " << b.size() << "\n";  
}

输出:

a.size() = 0
b.size() = 4

移动赋值运算符

这是一个特殊函数,允许一个对象从另一个对象获取资源的所有权,而无需复制。

用户自定义移动赋值运算符

程序员可以自定义移动赋值运算符。

例子:

#include <iostream>
#include <cstring>class MyString {char* data;public:// ConstructorMyString(const char* str = "") {data = new char[strlen(str) + 1];strcpy(data, str);}// User-defined move assignment operatorMyString& operator=(MyString&& other) {std::cout << "Move assignment called\n";if (this != &other) {// Free old memorydelete[] data;// Steal the pointerdata = other.data;// Set source to nullother.data = nullptr; }return *this;}// Destructor~MyString() {delete[] data;}void print() const {if (data)std::cout << data << "\n";elsestd::cout << "[empty]\n";}
};
int main() {MyString a("Hello");MyString b("World");b = std::move(a);  b.print();  a.print();  
}

输出:

Move assignment called
Hello
[empty]

移动赋值运算符的必要性

  • 提升性能 - 移动赋值运算符通过转移资源而非复制资源来提高速度,尤其对于大型对象而言。

  • 减少内存占用 - 它通过重用现有资源避免在内存中创建不必要的重复项。

  • 高效处理临时对象 - 移动赋值运算符允许对象从临时值中获取数据所有权,而无需进行代价高昂的复制操作。

自己实现字符串move拷贝构造和move赋值运算符重载

示例

#include <iostream>// - [https://www.youtube.com/@TheCherno](https://www.youtube.com/@TheCherno)// ## C++基础
// - [lvalues and rvalues in C++](https://www.youtube.com/watch?v=fbYknr-HPYE)
// - [std::move and the Move Assignment Operator in C++](https://www.youtube.com/watch?v=OWNeCTd7yQE)
// - [Move Semantics in C++](https://www.youtube.com/watch?v=ehMg6zvXuMY)
// - [SMART POINTERS in C++ (std::unique_ptr, std::shared_ptr, std::weak_ptr)](https://www.youtube.com/watch?v=UOB7-B2MfwA)
// - [Weak Pointers in C++ (std::weak_ptr)](https://www.youtube.com/watch?v=M0GLQEfplxs)class MyString
{public:MyString() = default;MyString(const char* s){std::cout << "Created!" << std::endl;m_Size = strlen(s);m_Data = new char[m_Size];memcpy(m_Data, s, m_Size);}MyString(const MyString& other): m_Size(other.m_Size){std::cout << "Copied!" << std::endl;m_Data = new char[m_Size];memcpy(m_Data, other.m_Data, m_Size);}MyString(MyString&& other) noexcept{std::cout << "Moved!" << std::endl;m_Data = other.m_Data;m_Size = other.m_Size;other.m_Data = nullptr;other.m_Size = 0;}MyString& operator=(const MyString& other) noexcept{std::cout << "Assigned!" << std::endl;if (this == &other)return *this;delete[] m_Data;m_Size = other.m_Size;m_Data = new char[m_Size];memcpy(m_Data, other.m_Data, m_Size);return *this;}MyString& operator=(MyString&& other) noexcept{std::cout << "Move Assigned!" << std::endl;if (this == &other)return *this;delete[] m_Data;m_Data = other.m_Data;m_Size = other.m_Size;other.m_Data = nullptr;other.m_Size = 0;return *this;}~MyString(){std::cout << "Destroyed!" << std::endl;delete[] m_Data;}void Print() const{for (unsigned int i = 0; i < m_Size; i++)std::cout << m_Data[i];std::cout << std::endl;}private:char* m_Data = nullptr;unsigned int m_Size = 0;
};class Entity
{
public:Entity(const MyString& name): m_Name(name){}Entity(MyString&& name): m_Name(std::move(name)){}
private:MyString m_Name;
};int main()
{{MyString hello = "Hello World!";Entity e1(hello);                  // CopyEntity e2(std::move(hello));       // Move}std::cout << "---------------------" << std::endl;MyString apple = "Apple";MyString dest;std::cout << "Apple: ";apple.Print();std::cout << "Dest: ";dest.Print();dest = std::move(apple); // Move Assignmentstd::cout << "Apple: ";apple.Print();std::cout << "Dest: ";dest.Print();return 0;
}

输出

Created!
Copied!
Moved!
Destroyed!
Destroyed!
Destroyed!
---------------------
Created!
Apple: Apple
Dest: 
Move Assigned!
Apple: 
Dest: Apple
Destroyed!
Destroyed!

参考资料

  • Move Assignment Operator in C++ 11
  • std::move and the Move Assignment Operator in C++
  • How to Implement Move Assignment Operator in C++?
  • Move assignment operator
  • Move Constructors and Move Assignment Operators (C++)
  • 移动构造函数和移动赋值运算符 (C++)
http://www.dtcms.com/a/610042.html

相关文章:

  • Java:startsWith()
  • 【Linux】进程间通信(四)消息队列、信号量与内核管理ipc资源机制
  • php整站最新版本下载html5 网站开发工具
  • wordpress更换网站数据库中国网络公司排名前十
  • 病床脚轮制动系统公差优化:CETOL 6σ建模与装配顺序重构,根治对中漂移
  • 专注网站建设与制作做网站费用多少钱
  • 潍坊网站建设哪家专业门户网站php源码
  • 【架构】安全
  • 大数据生态Sql引擎
  • 使用 .NET 8 构建 RESTful Web API
  • Servlet进阶
  • 计算机视觉——图像数据增强从原理到落地的全解析
  • 【MATLAB例程】2雷达二维目标跟踪滤波系统-UKF(无迹卡尔曼滤波)实现,目标匀速运动模型(带扰动)。附代码下载链接
  • yolov5/8/9/10/11/12/13+deep-oc-sort算法的目标跟踪实现
  • 网站维护花费个人备案网站做app
  • 用Scrapyd爬取豆瓣图书Top250
  • 数据分析笔记06:假设检验
  • 【论文阅读17】-LLM-TSFD:一种基于大型语言模型的工业时间序列人机回路故障诊断方法
  • Elasticsearch 面试题精编(26题|含答案|分类整理)
  • 专业格泰网站建设宝塔 怎么做网站
  • app做好了网站怎么做1千万人网站维护成本
  • 网站设计价格大概多少宁波seo关键词优化服务
  • AIGC总结二:Stable Diffusion 的训练方式、使用流程、硬件要求、实际应用场景
  • 大疆Action 6 ,pocket3及 action 5 Pro 该如何选择?
  • 银川网站开发培训案例分析网站
  • 谷歌云数据库服务概览:关系型与 NoSQL 的多元选择与应用场景解析
  • 自动驾驶环境下的多目标检测与识别_YOLOv8改进实践
  • 运动学模型推导 + 离散化 + 工程化版本(适用于前方单舵轮 AGV / 自动驾驶 / MPC)
  • 微信小程序中 WebView 组件的使用与应用场景
  • UE5导入的CAD文件零件如何被Merge?