C++11 引入了移动语义,通过右值引用和 std::move() 函数来实现资源的有效转移,避免了不必要的拷贝。下面是一个简单的例子来说明移动语义的实现:
#include <iostream>
#include <string>
#include <vector>
#include <utility> // for std::move
class MyString {
public:
MyString() : data(nullptr), size(0) {}
MyString(const char* str) {
size = std::strlen(str);
data = new char[size + 1];
std::strcpy(data, str);
}
MyString(MyString&& other) noexcept : data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
}
~MyString() {
delete[] data;
}
MyString& operator=(MyString&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
}
return *this;
}
// Other member functions like copy constructor, assignment operator, etc.
private:
char* data;
int size;
};
int main() {
MyString s1("Hello, world!");
MyString s2 = std::move(s1); // Move semantics here
std::cout << "s1: " << s1.data << ", size: " << s1.size << std::endl;
std::cout << "s2: " << s2.data << ", size: " << s2.size << std::endl;
return 0;
}
在这个例子中,我们定义了一个简单的 MyString
类,它包含一个指向字符数组的指针和一个表示字符串大小的整数。我们实现了移动构造函数和移动赋值运算符,它们接受右值引用作为参数,并将资源从源对象转移到目标对象。这样,当我们将 s1
传递给 s2
时,资源不会发生不必要的拷贝,而是直接转移。
需要注意的是,移动语义并不总是适用的。在某些情况下,拷贝语义可能更合适。因此,在设计类时,我们需要根据实际情况权衡是否使用移动语义。