【Qt】std::shared_ptr<>与std::make_shared<>

cpp 复制代码
std::shared_ptr<int>

这是 C++11 引入的:

txt 复制代码
智能指针(Smart Pointer)

完整理解:

txt 复制代码
一个"自动管理 int 对象生命周期"的指针

它属于:

cpp 复制代码
#include <memory>

中的内容。


一、先看传统指针的问题

传统写法:

cpp 复制代码
int* p = new int(10);

这里:

  • new
    → 在堆上申请内存

返回:

txt 复制代码
int*

也就是普通指针。


问题:容易内存泄漏

你必须手动:

cpp 复制代码
delete p;

否则:

txt 复制代码
内存泄漏

例如:

cpp 复制代码
void test()
{
    int* p = new int(10);

    return; // 忘记delete
}

这块内存永远回收不了。


二、shared_ptr 的作用

于是 C++11 提供:

cpp 复制代码
std::shared_ptr

用于:

txt 复制代码
自动释放内存

三、这句代码是什么意思

cpp 复制代码
std::shared_ptr<int> p;

拆开看:


1. shared_ptr

表示:

txt 复制代码
共享所有权智能指针

意思:

txt 复制代码
多个指针可以共同拥有同一个对象

内部使用:

txt 复制代码
引用计数

管理生命周期。


2. <int>

模板参数。

表示:

txt 复制代码
它管理的是 int 类型对象

类似:

cpp 复制代码
std::vector<int>

里的 <int>


3. 整体意思

cpp 复制代码
std::shared_ptr<int> p;

等价理解:

txt 复制代码
定义一个"管理 int 对象"的智能指针

四、最常见正确写法

通常这样创建:

cpp 复制代码
auto p = std::make_shared<int>(10);

意思:

txt 复制代码
在堆上创建 int(10)
并用 shared_ptr 管理

五、内部发生了什么

cpp 复制代码
auto p = std::make_shared<int>(10);

大致等价于:

cpp 复制代码
int* raw = new int(10);

但:

txt 复制代码
shared_ptr 会自动 delete

你不需要:

cpp 复制代码
delete

六、使用方式


读取值

cpp 复制代码
std::cout << *p;

输出:

txt 复制代码
10

因为:

cpp 复制代码
*p

是解引用。


修改值

cpp 复制代码
*p = 20;

七、shared(共享)是什么意思

这是 shared_ptr 最核心部分。


多个 shared_ptr 指向同一对象

cpp 复制代码
auto p1 = std::make_shared<int>(100);

auto p2 = p1;

此时:

txt 复制代码
p1 和 p2
共同拥有同一个 int

内存里:

txt 复制代码
      +--------+
p1 -->| int100 |
p2 -->|        |
      +--------+

八、引用计数

shared_ptr 内部有:

txt 复制代码
引用计数(Reference Count)

创建时

cpp 复制代码
auto p1 = std::make_shared<int>(100);

计数:

txt 复制代码
1

拷贝后

cpp 复制代码
auto p2 = p1;

计数:

txt 复制代码
2

一个对象销毁

cpp 复制代码
p2 离开作用域

计数:

txt 复制代码
1

最后一个销毁

txt 复制代码
计数=0

自动:

cpp 复制代码
delete

释放内存。


九、例子

cpp 复制代码
#include <iostream>
#include <memory>

int main()
{
    auto p1 = std::make_shared<int>(10);

    {
        auto p2 = p1;

        std::cout << p1.use_count() << std::endl;
    }

    std::cout << p1.use_count() << std::endl;
}

输出:

txt 复制代码
2
1

十、为什么推荐 make_shared

推荐:

cpp 复制代码
auto p = std::make_shared<int>(10);

不推荐:

cpp 复制代码
std::shared_ptr<int> p(new int(10));

因为:


make_shared 优点

1. 性能更好

一次内存分配。


2. 更安全

避免异常导致泄漏。


3. 代码更简洁


十二、如何判断为空

cpp 复制代码
if (b)
{
    // 非空
}
else
{
    // 空
}

十三、shared_ptr 内存结构

内部大概:

txt 复制代码
shared_ptr
   │
   ├── 指向对象
   │
   └── 引用计数控制块

例如:

txt 复制代码
+----------------+
| control block  |
| ref_count = 2  |
+----------------+
         |
         v
     +-------+
     | int10 |
     +-------+

十四、shared_ptr 最大问题


循环引用

例如:

cpp 复制代码
class A
{
    shared_ptr<B> b;
};

class B
{
    shared_ptr<A> a;
};

结果:

txt 复制代码
A 引用 B
B 引用 A

引用计数永远不为 0。

导致:

txt 复制代码
内存泄漏

解决方法

使用:

cpp 复制代码
std::weak_ptr

打破循环引用。


十五、智能指针三兄弟


1. unique_ptr

独占所有权。

txt 复制代码
一个对象只能有一个主人

不能复制。

性能最好。


2. shared_ptr

共享所有权。

可多个指针共享。

有引用计数开销。


3. weak_ptr

弱引用。

不增加引用计数。

用于:

  • 观察对象
  • 打破循环引用

十六、现代 C++ 推荐

现代 C++:

txt 复制代码
尽量不要直接 new/delete

推荐:

cpp 复制代码
make_unique
make_shared

RAII 自动管理资源。


十七、Qt 中的对应关系

Qt 里类似:

STL Qt
shared_ptr QSharedPointer
weak_ptr QWeakPointer
unique_ptr QScopedPointer

不过现代 Qt 项目:

很多人直接使用 STL 智能指针。

相关推荐
z落落9 分钟前
C#WinForm控件实战:Panel与单选框动态创建
开发语言·c#
ptc学习者10 分钟前
python 中描述符@property property 大概的样子
开发语言·python
zmzb010311 分钟前
Python课后习题训练记录Day129
开发语言·python
张忠琳20 分钟前
【Go 1.26.4】Golang Map 深度解析
开发语言·后端·golang
Vertira20 分钟前
如何对QT开发的软件进行打包[已解决]
开发语言·qt
AI人工智能+电脑小能手22 分钟前
【大白话说Java面试题 第110题】【并发篇】第10题:CAS 存在哪些问题?
java·开发语言·面试
石一峰69930 分钟前
C 语言函数设计模式实战经验
c语言·开发语言·设计模式
sitellla37 分钟前
Pydub:用 Python 处理音频,不写废话
开发语言·python·其他·音视频
xingyuzhisuan1 小时前
缓存命中率提升方案:从 30% 优化至 82% 全流程优化记录
java·开发语言·缓存·ai
郑洁文1 小时前
基于Python的恶意流量监测系统的设计与实现
开发语言·python