首页 > 后端开发 > C++ > 正文

C++unique_ptr移动语义与转移所有权

P粉602998670
发布: 2025-09-11 10:04:01
原创
489人浏览过
unique_ptr的移动语义实现资源安全转移,禁止拷贝避免双重释放,通过移动构造和赋值将所有权从源指针转移至目标,源变为空,确保独占性。

c++unique_ptr移动语义与转移所有权

unique_ptr
登录后复制
的移动语义是其核心特性,它允许你安全地将一个动态分配对象的所有权从一个
unique_ptr
登录后复制
实例转移到另一个,而无需进行深度拷贝。这本质上意味着资源(比如堆上的对象)的所有权可以被“挪走”,原有的
unique_ptr
登录后复制
随即变为空,确保始终只有一个
unique_ptr
登录后复制
管理该资源,从而避免了双重释放等问题。

当我第一次接触

unique_ptr
登录后复制
时,它给我最大的感受就是“安全感”。那种独占所有权的设计,配合RAII,简直是管理堆内存的福音。而这份安全感的核心,很大程度上就来源于它的移动语义。

想象一下,你有一个

unique_ptr<MyObject> ptr1(new MyObject());
登录后复制
,现在你想把这个
MyObject
登录后复制
的所有权交给另一个
unique_ptr
登录后复制
,比如
ptr2
登录后复制
。如果允许拷贝,那就会出现两个
unique_ptr
登录后复制
指向同一个
MyObject
登录后复制
,当它们各自析构时,就会尝试两次
delete
登录后复制
,这绝对是灾难。
unique_ptr
登录后复制
很聪明,它直接禁用了拷贝构造函数和拷贝赋值运算符。

但有时候,我们确实需要“传递”这个资源。比如,一个函数创建了一个对象,然后想把它返回给调用者;或者在一个容器里,我们想把一个

unique_ptr
登录后复制
从一个位置移动到另一个位置。这时候,移动语义就派上用场了。

微软文字转语音
微软文字转语音

微软文本转语音,支持选择多种语音风格,可调节语速。

微软文字转语音 0
查看详情 微软文字转语音

立即学习C++免费学习笔记(深入)”;

unique_ptr
登录后复制
提供了移动构造函数和移动赋值运算符。当使用
std::move
登录后复制
将一个
unique_ptr
登录后复制
实例作为右值引用传递时,实际上发生的是所有权的转移:

  1. unique_ptr
    登录后复制
    所持有的原始指针(指向
    MyObject
    登录后复制
    的地址)被“偷走”了。
  2. 目标
    unique_ptr
    登录后复制
    获得了这个原始指针,现在它拥有了
    MyObject
    登录后复制
  3. unique_ptr
    登录后复制
    的原始指针被置为
    nullptr
    登录后复制
    ,它不再管理任何资源。

这意味着,一旦移动完成,你不能再通过源

unique_ptr
登录后复制
访问原来的
MyObject
登录后复制
了,因为它已经“空”了。这完美地实现了独占所有权的概念:资源从A挪到了B,A就不再拥有它了。这种机制不仅安全,而且高效,因为它避免了昂贵的深拷贝操作,仅仅是几个指针的赋值和置空。

#include <iostream>
#include <memory>
#include <vector>
#include <string>

class MyResource {
public:
    int id_;
    MyResource(int id) : id_(id) {
        std::cout << "MyResource " << id_ << " constructed." << std::endl;
    }
    ~MyResource() {
        std::cout << "MyResource " << id_ << " destructed." << std::endl;
    }
    void doSomething() {
        std::cout << "MyResource " << id_ << " doing something." << std::endl;
    }
};

std::unique_ptr<MyResource> createResource(int id) {
    // 函数内部创建unique_ptr,并返回
    // 这里会隐式地发生移动
    return std::make_unique<MyResource>(id); 
}

int main() {
    std::cout << "--- Initial unique_ptr ---" << std::endl;
    std::unique_ptr<MyResource> ptr1 = std::make_unique<MyResource>(101);
    if (ptr1) {
        ptr1->doSomething();
    }

    std::cout << "\n--- Moving ownership ---" << std::endl;
    std::unique_ptr<MyResource> ptr2 = std::move(ptr1); // 显式移动
    if (ptr1) { // ptr1 现在是空的
        std::cout << "ptr1 still holds resource!" << std::endl;
    } else {
        std::cout << "ptr1 is now null." << std::endl;
    }
    if (ptr2) {
        ptr2->doSomething(); // ptr2 现在拥有资源
    }

    std::cout << "\n--- Moving from function return ---" << std::endl;
    std::unique_ptr<MyResource> ptr3 = createResource(202); // 隐式移动
    if (ptr3) {
        ptr3->doSomething();
    }

    std::cout << "\n--- Moving into a vector ---" << std::endl;
    std::vector<std::unique_ptr<MyResource>> resources;
    resources.push_back(std::move(ptr2)); // 将ptr2持有的资源移动到vector中
    // ptr2 再次变为空
    if (ptr2) {
        std::cout << "ptr2 still holds resource after push_back!" << std::endl;
    } else {
        std::cout << "ptr2 is now null after push_back." << std::endl;
    }
    resources.push_back(std::move(ptr3)); // 将ptr3持有的资源移动到vector中
    // ptr3 再次变为空
    if (ptr3) {
        std::cout << "ptr3 still holds resource after push_back!" << std::endl;
    } else {
        std::cout << "ptr3 is now null after push_back." << std::endl;
    }

    std::cout << "\n--- Accessing resources in vector ---" << std
登录后复制

以上就是C++unique_ptr移动语义与转移所有权的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号