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++)
