当前位置: 首页 > news >正文

C++手写智能指针

1.普通指针的问题

普通指针(裸指针)在C++中提供了强大的灵活性,但也带来了诸多问题:

  1. 内存泄漏:忘记释放动态分配的内存。

  2. 悬空指针:访问已释放的内存区域。

  3. 双重释放:多次释放同一块内存。

  4. 所有权不明确:不知道谁应该负责释放内存。

    void problemExample() {int* raw_ptr = new int(42);  // 动态分配// 如果这里发生异常或提前返回,内存将泄漏if (some_condition) return;delete raw_ptr;  // 必须手动释放
    }

2. C++智能指针

智能指针是C++标准库(在 <memory> 头文件中)提供的类模板,它们通过RAII(Resource Acquisition Is Initialization) 机制来管理动态分配的内存(或其他资源)。

核心思想: 将裸指针(raw pointer)封装在一个对象中。当这个对象离开其作用域被销毁时,它的析构函数会自动调用 delete 或 delete[] 来释放它所拥有的内存。这有效地防止了由于忘记手动释放内存而导致的内存泄漏

C++11引入了三种主要的智能指针:

2.1 std::unique_ptr

  • 独占所有权,不能拷贝只能移动

    同一时间只能有一个 unique_ptr 拥有某个对象。当 unique_ptr 被销毁时,它指向的对象也会被自动销毁。它不能被复制,只能被移动(std::move)。

  • 轻量级,零额外开销(与裸指针相同)

  • 离开作用域时自动释放内存

2.2 std::shared_ptr

  • 共享所有权,使用引用计数

    多个 shared_ptr 可以同时“拥有”同一个对象。它通过引用计数机制来跟踪有多少个 shared_ptr 共享同一对象。当最后一个 shared_ptr 被销毁时,对象才会被释放。

  • 多个指针可以指向同一对象

  • 当最后一个引用被销毁时释放内存

  • 线程安全:引用计数的操作是原子性的(线程安全)

  • 循环引用问题:需要与 std::weak_ptr 配合使用

2.3 std::weak_ptr

  • 不增加引用计数的共享指针

  • 解决shared_ptr的循环引用问题

  • 需要转换为shared_ptr才能访问对象

3. 手动实现简化版智能指针

3.1 实现SimpleUniquePtr,它模仿 std::unique_ptr 的独占所有权特性。

#include <iostream>
#include <utility> // for std::swaptemplate <typename T>
class SimpleUniquePtr {
private:T* ptr_ = nullptr;// 防止拷贝SimpleUniquePtr(const SimpleUniquePtr&) = delete;SimpleUniquePtr& operator=(const SimpleUniquePtr&) = delete;public:// 默认构造函数SimpleUniquePtr() = default;// 构造函数,接管裸指针explicit SimpleUniquePtr(T* ptr) : ptr_(ptr) {}// 移动构造函数:接管另一个智能指针的资源,并将原指针置空SimpleUniquePtr(SimpleUniquePtr&& other) noexcept : ptr_(other.ptr_) {other.ptr_ = nullptr;}// 移动赋值运算符SimpleUniquePtr& operator=(SimpleUniquePtr&& other) noexcept {// 先清理自己当前拥有的资源delete ptr_;// 接管对方的资源ptr_ = other.ptr_;// 将对方的指针置空other.ptr_ = nullptr;return *this;}// 析构函数:释放资源~SimpleUniquePtr() {delete ptr_;}// 重载 * 运算符,解引用T& operator*() const {return *ptr_;}// 重载 -> 运算符,访问成员T* operator->() const {return ptr_;}// 获取被封装的裸指针(但不释放所有权)T* get() const {return ptr_;}// 释放资源的所有权,返回裸指针,并将内部指针置为空T* release() {T* released_ptr = ptr_;ptr_ = nullptr;return released_ptr;}// 重置资源:先删除当前拥有的,再接管新的void reset(T* new_ptr = nullptr) {// 防止自我重置时先被删除if (ptr_ != new_ptr) {delete ptr_;ptr_ = new_ptr;}}// 交换两个智能指针void swap(SimpleUniquePtr& other) noexcept {using std::swap;swap(ptr_, other.ptr_);}// 检查是否拥有有效对象explicit operator bool() const {return ptr_ != nullptr;}
};// 为我们的智能指针特化 std::swap,提供高效交换
template <typename T>
void swap(SimpleUniquePtr<T>& lhs, SimpleUniquePtr<T>& rhs) noexcept {lhs.swap(rhs);
}// --- 示例使用 ---
class MyClass {
public:MyClass() { std::cout << "MyClass constructed\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }void sayHello() { std::cout << "Hello from MyClass!\n"; }
};int main() {std::cout << "Creating SimpleUniquePtr...\n";SimpleUniquePtr<MyClass> ptr1(new MyClass()); // 构造函数ptr1->sayHello(); // 使用 -> 运算符(*ptr1).sayHello(); // 使用 * 运算符std::cout << "Moving ownership to ptr2...\n";SimpleUniquePtr<MyClass> ptr2 = std::move(ptr1); // 使用移动构造函数if (!ptr1) { // 使用 bool 转换std::cout << "ptr1 is now empty.\n";}if (ptr2) {std::cout << "ptr2 owns the object.\n";ptr2->sayHello();}std::cout << "Exiting main scope...\n";// ptr2 离开作用域,析构函数自动调用 delete,MyClass 被销毁// ptr1 是空的,析构函数什么都不做return 0;
}

输出结果:

http://www.dtcms.com/a/347455.html

相关文章:

  • 高等数学 9.1多元函数的基本概念
  • 力扣每日一刷Day 15
  • 在github上通过dmca数字版权申诉侵权并删除侵权仓库
  • 图结构使用 Louvain 社区检测算法进行分组
  • P9246 [蓝桥杯 2023 省 B] 砍树
  • 蓝桥杯算法之基础知识(2)——Python赛道
  • ComfyUI Portrait Master肖像大师中文版
  • TopK问题(堆排序)-- go
  • 牛客面经2 京东社招-002
  • 知识蒸馏 Knowledge Distillation 序列的联合概率 分解成 基于历史的条件概率的连乘序列
  • 基于SpringBoot的招聘系统源码
  • 破解秘籍——hashcat使用宝典
  • 商超场景徘徊识别误报率↓79%!陌讯多模态时序融合算法落地优化
  • 书写本体论视域下的文字学理论重构
  • 防范瓦斯爆炸:AI摄像机如何杜绝煤矿井下违规抽烟?
  • 复杂工业场景误报率↓85%!陌讯多模态火焰识别算法实战解析
  • ⸢ 零 ⸥ ⤳ 安全体系构建内容结构
  • 卷积神经网络的基本概念
  • 【码蹄杯】2025年本科组省赛第一场
  • 解决Node.js安装与npx命令问题
  • Stm32通过ESP8266 WiFi连接阿里云平台
  • 使用Lora微调大模型介绍篇
  • 【Python】新手入门:Python标准库有哪些常用模块?
  • 使用Screenpipe+本地大模型实现私人助手Agent
  • 【小宁学习日记4 Python】Python 变量与标识符全解:编程入门的基石
  • 简单AI:搜狐公司旗下AI绘画产品
  • 最新短网址源码,防封。支持直连、跳转。 会员无广
  • 部署PG一主一从
  • 使用Proxifier+vmware碰到的一些问题
  • GEO优化服务商:AI时代数字经济的新引擎——解码行业发展与技术创新实践