卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

  • 面向对象

  • STL 与容器

  • 内存管理

  • C++11 与现代 C++

  • 智能指针

    • 什么是智能指针,C++中有哪几种智能指针
      • 简要回答
      • 详细回答
      • 代码示例
      • 知识拓展
    • 智能指针的实现原理是什么?
    • C++11中的智能指针线程安全性
  • 并发与 I/O

# 什么是智能指针,C++中有哪几种智能指针?

# 简要回答

智能指针 是一种自动管理动态内存的工具类,用于防止内存泄漏。

c++提供了三种常用的指针 unique,share,weak。

unique独占所有权,指针指向的对象只能有这一个指针。

shared共享所有权,指针可以有多个,每释放一个指针变量,指针计数减少一个,到零时释放被指对象,常用来计数。

weak指针是一种弱指针,不拥有资源,防止循环引用,如果对象在指针还在时被释放,也不会报错,不受影响。

# 详细回答

提到智能指针就必须知道RAII的编程思想,RAII是C++语言的一种管理资源、避免泄漏的惯用法。

智能指针是用来自动管理动态内存的工具,通过封装原生指针在适当时机释放内存。

unique_ptr:独占智能指针,独占对象所有权,同一时间只能有一个指针指向一个对象,适合独占资源的场景;禁止拷贝构造和拷贝赋值,支持移动语义。

share_ptr:一个共享所有权的智能指针,允许对象之间进行复制或者赋值,展示出来的就是值语义。

使用引用计数的观点,当对象之间进行复制或者赋值的时候,引用计数会加+1,当最后一个对象销毁的时候,引用计数减为0,此时会回收托管的空间。

weak_ptr:常用于解决share_ptr循环引用的问题,weak_ptr类的对象可以指向shared_ptr,并且不会改变shared_ptr的引用计数。一旦最后一个shared_ptr被销毁时,对象就会被释放。

智能指针则深刻的体现了这种思想。在现代 C++ 编程中,标准库包含智能指针,该指针用于确保程序不存在内存和资源泄漏且是异常安全的。

智能指针本质就是一个类模板,它可以创建任意的类型的指针对象,当智能指针对象使用完后,对象就会自动调用析构函数去释放该指针所指向的空间。

# 代码示例

  1. 独占指针 std::unique_ptr 独占指针,不能拷贝,只能移动,一个资源只能被一个unique管理
#include <memory>
std::unique_ptr<int> ptr1(new int(10));
// std::unique_ptr<int> ptr2 = ptr1.  错误,不可拷贝
std::unique_ptr<int> ptr2 = std::move(ptr1); //正确
1
2
3
4
  1. 共享指针 std::shared_ptr 共享指针,多个指针可以共享一个资源,使用计数器控制资源释放
#include <memory>
std::shared_ptr<int> p1 = std::make_shared<int>(10);
std::shared_ptr<int> p2 = p1;  // 引用计数 +1
1
2
3
  1. 弱指针 用于观察共享指针的管理资源,不增加引用计数,防止循环引用
std::shared_ptr<int> sp = std::make_shared<int>(42);
std::weak_ptr<int> wp = sp;  // 不增加引用计数
1
2
  1. 三个指针同时运用的例子
#include <iostream>
#include <memory>
using namespace std;

class Animal {
public:
    Animal(string name) : name_(name) {
        cout << "Animal " << name_ << " created.\n";
    }
    ~Animal() {
        cout << "Animal " << name_ << " destroyed.\n";
    }
    void speak() {
        cout << "Hi, I'm " << name_ << endl;
    }

private:
    string name_;
};

int main() {
    // 1. 使用 unique_ptr 管理一只独占的小狗
    unique_ptr<Animal> dog = make_unique<Animal>("Dog");
    dog->speak();

    // 2. 使用 shared_ptr 管理一只共享的猫
    shared_ptr<Animal> cat1 = make_shared<Animal>("Cat");
    {
        shared_ptr<Animal> cat2 = cat1;  // 共享一份资源
        cout << "Cat use_count = " << cat1.use_count() << endl; // 应该是 2
    } // cat2 离开作用域,引用计数 -1
    cout << "Cat use_count = " << cat1.use_count() << endl; // 应该是 1

    // 3. 使用 weak_ptr 观察 shared_ptr 管理的猫
    weak_ptr<Animal> weakCat = cat1;
    if (auto catShared = weakCat.lock()) {
        catShared->speak();  // 还活着,可以访问
    }

    // cat1 离开作用域后,猫对象自动销毁
    return 0;
}
//==================================//
// 输出结果
Animal Dog created.
Hi, I'm Dog
Animal Cat created.
Cat use_count = 2
Cat use_count = 1
Hi, I'm Cat
Animal Dog destroyed.
Animal Cat destroyed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

# 知识拓展

  • 智能指针图解 image

    • 什么是RAII机制? RAII 全称: Resource Acquisition Is Initialization(资源获取即初始化)

    即:当你用一个智能指针去创建对象时,它立刻就会接管资源(如内存); 当智能指针生命周期结束(如离开作用域、函数返回等),它会自动调用析构函数,把资源安全释放掉,不需要你手动 delete。

    通俗的讲就是,RAII就是“我拿到资源我就负责到底,我走了我就顺手把它销毁”

      {
        std::unique_ptr<int> ptr(new int(10)); // 构造:自动接管资源
        // ...用 ptr 做点什么
    } // 离开作用域,析构:自动释放内存
    
    1
    2
    3
    4
    • 记忆口诀

    unique 独家专属,不能复制

    shared 合作共赢,数清关系

    weak 偷偷观察,不管后事

    RAII 是关键,内存不手动

Last Updated: 3/10/2026, 6:08:48 PM

← C++中的协程概念及实现 智能指针的实现原理是什么? →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪