ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【C++】023、移动语义深拷贝

2026/8/6 4:50:59 拓冰建站 浏览量
【C++】023、移动语义深拷贝 一、移动语言是如何解决深拷贝的性能问题深拷贝会复制整个底层数据让源对象和目标对象都拥有自己独立的堆内存空间移动语义是转换底层资源的所有权将源对象的指针指向目标对象而不赋值底层数据时间复杂都为1移动语义将源对象的资源指针移动到目标对象并将源对象指针设置为nullptr这样源对象的析构操作就不会释放已经释放的资源了。二、代码示例移动构造函数与移动赋值操作符函数实现#include iostream #include cstring class MyString { private: char* m_data; size_t m_len; public: // ---------- 构造函数 ---------- MyString(const char* str ) : m_len(strlen(str)), m_data(new char[m_len 1]) { strcpy(m_data, str); } // ---------- 析构函数 ---------- ~MyString() { delete[] m_data; // 如果 m_data 是 nullptr安全无操作 } // // 1. 深拷贝构造O(n)昂贵 // MyString(const MyString other) : m_len(other.m_len), m_data(new char[m_len 1]) { strcpy(m_data, other.m_data); // 申请内存 复制数据 std::cout 深拷贝构造耗时 O(n) std::endl; } // // 2. 移动构造O(1)零开销 // MyString(MyString other) noexcept : m_data(other.m_data) // ① 窃取指针只复制地址 , m_len(other.m_len) { // ② 窃取长度 other.m_data nullptr; // ③ 关键置空源对象切断所有权 other.m_len 0; std::cout 移动构造O(1) 指针交换未复制任何数据 std::endl; } // // 3. 移动赋值O(1)对比深拷贝赋值 // MyString operator(MyString other) noexcept { if (this ! other) { delete[] m_data; // 释放自己的旧资源如果有 m_data other.m_data; // 窃取指针 m_len other.m_len; other.m_data nullptr; // 置空源对象 other.m_len 0; std::cout 移动赋值O(1) std::endl; } return *this; } };外部调用代码int main() { std::cout 场景1拷贝构造 vs 移动构造 std::endl; { MyString s1(HelloWorld); // 1. 普通构造分配堆内存 MyString s2(s1); // 2. 深拷贝构造申请新内存 复制10个字符 MyString s3(std::move(s1)); // 3. 移动构造只交换指针O(1) // 注意s1 现在是一个空壳m_data nullptr不能再读取其内容 // 如果取消下面这行注释程序会崩溃访问空指针。 // std::cout s1 内容: s1.c_str() std::endl; std::cout s2 内容: s2.c_str() (独立内存) std::endl; std::cout s3 内容: s3.c_str() (窃取了 s1 的资源) std::endl; } // 作用域结束s1(空)、s2、s3 各自析构不会双重释放 std::cout std::endl;三、移动语义操作中置空源对象的原因1、防止双重释放如果源对象的析构函数被调用时m_data还指向原来的地址他就会delete[]这块内存而目标对象也指向这块地址两个析构先后释放同一块内存进程立即崩溃。2、保证析构安全置空后源对象的析构函数执行delete[] m_data由于m_data是nullpdelete[]是无害的空操作。四、移动构造函数使用noexcept的原因C标准库承诺vector扩容必须提供强异常安全保证也就是扩容过程中如果抛出异常程序的状态必须安全地恢复到扩容前的状态但是移动构造函数会将源对象置为空了无法恢复所以加noexcept相当于向编译器承诺此操作不会抛异常让stl容器放心地使用移动从而达到最高性能。