首页 > 编程语言 >C++之智能指针

C++之智能指针

时间:2024-11-10 09:16:22浏览次数:3  
标签:std weak C++ 智能 shared unique ptr 指针

智能指针是C++中的一种资源管理工具,用于自动管理动态分配的内存。它们通过在不再需要时自动释放内存来防止内存泄漏。C++标准库提供了几种不同类型的智能指针,每种都有其特定的用途和行为。

主要的智能指针类型

  1. std::unique_ptr
  2. std::shared_ptr
  3. std::weak_ptr

1. std::unique_ptr

std::unique_ptr 是一种独占所有权的智能指针。它确保只有一个指针指向某个对象,并且当 std::unique_ptr 被销毁时,它所管理的对象也会被自动删除。

示例代码
#include <iostream>
#include <memory>

int main() {
    // 创建一个 unique_ptr,管理一个动态分配的 int 对象
    std::unique_ptr<int> ptr(new int(10));

    // 或者使用 make_unique (C++14 及以后)
    auto ptr2 = std::make_unique<int>(20);

    // 使用指针
    std::cout << "ptr: " << *ptr << std::endl;
    std::cout << "ptr2: " << *ptr2 << std::endl;

    // unique_ptr 不支持拷贝构造和赋值
    // std::unique_ptr<int> ptr3 = ptr; // 编译错误

    // 但是支持移动构造和赋值
    std::unique_ptr<int> ptr3 = std::move(ptr);
    std::cout << "ptr3: " << *ptr3 << std::endl;

    // 此时 ptr 已经为空
    if (!ptr) {
        std::cout << "ptr 已经为空" << std::endl;
    }

    return 0;
}

2. std::shared_ptr

std::shared_ptr 是一种共享所有权的智能指针。多个 std::shared_ptr 可以指向同一个对象,当最后一个 std::shared_ptr 被销毁时,它所管理的对象才会被删除。

示例代码
#include <iostream>
#include <memory>

int main() {
    // 创建一个 shared_ptr,管理一个动态分配的 int 对象
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10);

    // 创建另一个 shared_ptr,共享同一个对象
    std::shared_ptr<int> ptr2 = ptr1;

    // 使用指针
    std::cout << "ptr1: " << *ptr1 << ", 引用计数: " << ptr1.use_count() << std::endl;
    std::cout << "ptr2: " << *ptr2 << ", 引用计数: " << ptr2.use_count() << std::endl;

    // 创建第三个 shared_ptr,共享同一个对象
    std::shared_ptr<int> ptr3 = ptr1;
    std::cout << "ptr3: " << *ptr3 << ", 引用计数: " << ptr3.use_count() << std::endl;

    // 当最后一个 shared_ptr 被销毁时,对象会被删除
    return 0;
}

3. std::weak_ptr

std::weak_ptr 是一种观察型智能指针,它不增加引用计数,也不会阻止对象被删除。std::weak_ptr 主要用于解决循环引用问题。

示例代码
#include <iostream>
#include <memory>

int main() {
    // 创建一个 shared_ptr,管理一个动态分配的 int 对象
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10);

    // 创建一个 weak_ptr,观察同一个对象
    std::weak_ptr<int> wptr = ptr1;

    // 使用 weak_ptr 获取 shared_ptr
    if (auto sptr = wptr.lock()) {
        std::cout << "wptr 锁定的对象: " << *sptr << std::endl;
    } else {
        std::cout << "wptr 锁定的对象已失效" << std::endl;
    }

    // 释放最后一个 shared_ptr
    ptr1.reset();

    // 再次尝试锁定 weak_ptr
    if (auto sptr = wptr.lock()) {
        std::cout << "wptr 锁定的对象: " << *sptr << std::endl;
    } else {
        std::cout << "wptr 锁定的对象已失效" << std::endl;
    }

    return 0;
}

总结

  • std::unique_ptr:适用于独占所有权的场景,性能最高,推荐优先使用。
  • std::shared_ptr:适用于共享所有权的场景,内部使用引用计数管理对象生命周期。
  • std::weak_ptr:主要用于解决循环引用问题,不增加引用计数。

通过合理使用这些智能指针,可以有效地管理动态分配的内存,避免内存泄漏和其他资源管理问题。

标签:std,weak,C++,智能,shared,unique,ptr,指针
From: https://blog.csdn.net/weixin_42300449/article/details/143655328

相关文章

  • Open3D (C++) 旋转矩阵转欧拉角公式推导及过程实现
    目录一、概述1.1原理1.2实现步骤1.3应用场景1.4注意事项二、关键函数2.1头文件2.2主要函数三、完整代码三、结果展示一、概述  将旋转矩阵转换为欧拉角是逆向理解三维对象姿态的一种方法。旋转矩阵是一个3x3的正交矩阵,它描述了在三维空......
  • C++-练习-67
    题目:考虑下面的结构声明structcustomer{        charfullname[35];        doublepayment;};编写一个程序,它从栈中添加和删除customer结构(栈用Stack类声明)。每次customer结构被删除时,其payment的值都被添加到总数中,并报告总数。源代码:test.h#if......
  • C++代码优化(二): 区分接口继承和实现继承
    目录1.引言2.接口继承3.实现继承4.如何选择接口继承与实现继承5.完整实例6.总结1.引言        在C++中,区分接口继承和实现继承是一种良好的编程实践,有助于提高代码的可维护性、可读性和可扩展性。接口继承通常指的是从基类继承纯虚函数(purevirtualfunctions......
  • 华为OD机试2024年E卷-MVP争夺战[100分]( Java | Python3 | C++ | C语言 | JsNode | Go
    题目描述在星球争霸篮球赛对抗赛中,最大的宇宙战队希望每个人都能拿到MVP,MVP的条件是单场最高分得分获得者。可以并列所以宇宙战队决定在比赛中尽可能让更多队员上场,并且让所有得分的选手得分都相同,然而比赛过程中的每1分钟的得分都只能由某一个人包揽。输入描述输入第一行......
  • 华为OD机试2024年E卷-AI识别面板[100分]( Java | Python3 | C++ | C语言 | JsNode | Go
    题目描述AI识别到面板上有N(1≤N≤100)个指示灯,灯大小一样,任意两个之间无重叠。由于AI识别误差,每次别到的指示灯位置可能有差异,以4个坐标值描述AI识别的指示灯的大小和位置(左上角x1,y1,右下角x2,y2),请输出先行后列排序的指示灯的编号,排序规则:每次在尚未排序的灯中挑选最高的......
  • 【C++】详细介绍:priority_queue的使用、适配器、deque介绍、仿函数
    目录一、介绍二、使用三、函数模版和类模板的区别四、适配器1、适配器适配栈扩展:2、deque(双端队列)缺省模版五、仿函数一、介绍(1)、priority_queue称为优先级队列,是一种容器适配器,不是队列也不是容器。(2)、该结构的底层是堆结构,默认是大堆,用模版参数来区分是大堆......
  • c++中使用using namespace的命名空间污染问题
    如果 a.h 中使用了 usingnamespaceaa;,并且 b.cpp 包含了 a.h,那么在 b.cpp 中可以直接使用 aa 命名空间中的内容,因为 usingnamespaceaa; 会被一并包含进来。解释usingnamespace 会将指定命名空间中的所有符号引入当前作用域。当 b.cpp 包含 a.h 时,a.h 中......
  • C++和C中的结构体兼容问题Anonymous non-C-compatible type given name for linkage p
    这个编译错误消息指的是,在typedef声明中引入了一个匿名非C兼容类型,编译器为了链接处理给它了一个名字,但它建议添加一个标签名称来显式命名该类型,以便更好地支持C语言的兼容性和跨文件链接。问题原因在C++中,匿名结构体和匿名联合体是合法的,它们可以在没有显式名称的情况下......
  • C++基础学习3
    //3.常量和变量://生活中的一些数据//有些数据不能变:血型、性别、圆周率//有些数据可以变:年龄、身高、体重、工资//在C语言中的描述://变量:能被改变的量//常量:不能被改变的量//intmain()//{// //创建一个变量// //int=类型、age=变量的名字、=是赋值的意思、23是数值// ......
  • c++ 题目4 平方之和
    简单时间限制:1000MS内存限制:128MB分数:100OI排行榜得分:12(0.1*分数+2*难度)描述小杨有 n 个正整数 a1​,a2​,…,an​,他想知道对于所有的 i(1≤i≤n),是否存在两个正整数 x 和 y 满足 x×x+y×y=ai​。输入描述第一行包含一个正整数 n,代表正整数数量。之后 n ......