【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 智能指针。

相关推荐
C^h6 小时前
c++ string
开发语言·c++
raindayinrain6 小时前
c++高性能--原子操作,无锁编程,操作顺序
开发语言·c++·性能优化
学逆向的6 小时前
C++ 合并命名空间
开发语言·c++·网络安全
Zhao-Jichao6 小时前
VS2026 打包 C++ 程序生成 EXE,借助 Installer Project 扩展工具
开发语言·c++
学逆向的7 小时前
C 局部静态变量
c语言·开发语言·网络安全
小徐不徐说7 小时前
C++ 接口与插件设计:从工厂注册到 Qt 动态插件
数据库·c++·qt·系统架构·程序设计
大都督会赢的7 小时前
C++第一节课
开发语言·c++
“AI国潮设计-小江”7 小时前
【AIGC实战】Python+Stable Diffusion打造“英歌舞财神”IP,解锁“马到成功”等爆款情绪营销文案设计
开发语言·人工智能·python·prompt·aigc
小王C语言8 小时前
Qt常用控件:容器类控件,标题分组框、标签页(浏览器标签)
开发语言·qt
TMedical8 小时前
MedPlanning 截骨模拟矫形功能
c++·图像处理·人工智能·qt·健康医疗