移动构造函数通过右值引用实现资源高效转移,避免深拷贝。1. 语法为 ClassName(ClassName&& other) noexcept,noexcept 提示不抛异常,利于STL优化。2. 函数内将原对象资源(如指针)转移至新对象,并将原对象指针置空,确保其可安全析构。3. 示例中 MyString(MyString&& other) 转移 data 指针并清空 other.data,防止双重释放。4. 注意事项:标记 noexcept、确保原对象合法、禁止使用已移动对象、所有资源均需转移。核心是资源所有权转移而非复制。
在C++中,移动构造函数用于高效地转移临时对象(右值)的资源,避免不必要的深拷贝。实现移动构造函数的关键是使用右值引用(&&)并合理转移资源,比如指针、动态内存、文件句柄等。
1. 基本语法和参数
移动构造函数的参数是一个右值引用,通常形式如下:
MyClass(MyClass&& other) noexcept
其中 noexcept 很重要,表示该函数不会抛出异常,有助于标准库(如std::vector)在扩容时优先使用移动而非拷贝。
2. 资源转移操作
在函数体内,你需要将原对象(other)的资源“移动”到新对象,同时让原对象处于可析构的合法状态(通常是空状态)。
立即学习“C++免费学习笔记(深入)”;
常见操作包括:
- 将指针成员赋值给新对象
- 将原对象的指针置为 nullptr,防止双重释放
- 其他资源(如句柄、缓冲区)也做类似处理
3. 实际代码示例
下面是一个简单但完整的例子,展示如何实现移动构造函数:
class MyString {
private:
char* data;
size_t size;
public:
// 构造函数
MyString(const char* str) {
size = strlen(str);
data = new char[size + 1];
strcpy(data, str);
}
// 移动构造函数
MyString(MyString&& other) noexcept
: data(nullptr), size(0)
{
data = other.data; // 转移指针
size = other.size;
other.data = nullptr; // 防止原对象释放资源
other.size = 0;
}
// 析构函数
~MyString() {
if (data) delete[] data;
}
// 禁用拷贝以简化示例(实际中应实现或删除)
MyString(const MyString&) = delete;
MyString& operator=(const MyString&) = delete;
};
4. 注意事项
编写移动构造函数时要注意以下几点:
- 确保标记为 noexcept,否则可能影响STL容器性能
- 移动后原对象仍需能安全析构,所以记得清空其资源指针
- 不要对已移动的对象做假设,它处于“已移动”状态,内容未定义
- 如果类有多个资源成员,全部都要正确转移
基本上就这些。只要掌握右值引用和资源转移逻辑,移动构造函数就不难实现。关键是理解“移动”的本质是所有权转移,不是复制。
c++ 标准库 strlen if 构造函数 析构函数 const char 指针 class public private operator delete 对象