当前位置:首页 » 《随便一记》 » 正文

【C++入门到精通】智能指针 auto_ptr、unique_ptr简介及C++模拟实现 [ C++入门 ]

1 人参与  2024年03月26日 13:50  分类 : 《随便一记》  评论

点击全文阅读


在这里插入图片描述

阅读导航

引言一、std::auto_ptr1. 简介2. 使用示例3. C++模拟实现 二、std::unique_ptr1. 简介2. 使用示例3. C++模拟实现 温馨提示

引言

在 C++ 中,智能指针是一种非常重要的概念,它能够帮助我们自动管理动态分配的内存,避免出现内存泄漏等问题。在上一篇文章中,我们了解了智能指针的基本概念和原理,本篇文章将继续介绍 auto_ptrunique_ptr 两种智能指针的概念及其在 C++ 中的模拟实现。通过学习这些内容,您将更好地理解智能指针的不同类型和使用场景,进一步提高程序的安全性和可靠性。让我们一起探索C++智能指针的精彩世界!

一、std::auto_ptr

?std::auto_ptr官方文档
在这里插入图片描述

1. 简介

std::auto_ptr 是 C++ 标准库中提供的一种智能指针类型,用于管理动态分配的内存资源。

std::auto_ptr 的主要特点是拥有所有权语义的转移。当一个 auto_ptr 对象拥有某个内存资源时,它可以将这个所有权转移给另一个 auto_ptr 对象。这意味着当一个 auto_ptr 对象被赋值给另一个 auto_ptr 对象或者被传递给一个函数时,原来的 auto_ptr 对象将不再拥有该资源,而是转移到了新的对象上

std::auto_ptr 类的定义在 <memory> 头文件中。使用 auto_ptr 需要包含该头文件,并使用 std 命名空间。

2. 使用示例

✅我们可以使用 auto_ptr 来管理动态分配的整型对象:

#include <iostream>#include <memory>int main() {    std::auto_ptr<int> ptr(new int(42));        std::cout << *ptr << std::endl;  // 输出:42        std::auto_ptr<int> ptr2 = ptr;  // 所有权转移        std::cout << *ptr2 << std::endl;  // 输出:42    // std::cout << *ptr << std::endl;  // 错误!ptr 不再拥有资源    return 0;}

??注意当一个 auto_ptr 对象转移所有权后,原来的对象将变为一个空指针。这可能导致程序出现意外的行为,因此需要谨慎使用。此外,std::auto_ptr 并不支持数组类型的内存资源管理,它只适用于单个对象。如果需要管理动态分配的数组,应该使用其他智能指针类型,如 std::unique_ptrstd::shared_ptr

总之,std::auto_ptr 是 C++ 标准库中提供的一种智能指针类型,具有所有权转移的特性。然而,由于其存在一些潜在的问题,已经在 C++17 中被废弃,推荐使用更先进的智能指针类型来代替

3. C++模拟实现

template<class T>class auto_ptr{public:    // 构造函数,接受一个指向动态分配的资源的指针    auto_ptr(T* ptr)        : _ptr(ptr)    {}    // 析构函数,在对象销毁时释放资源    ~auto_ptr()    {        if (_ptr)        {            cout << "delete:" << _ptr << endl;            delete _ptr;        }    }    // 拷贝构造函数,用于管理权转移    auto_ptr(auto_ptr<T>& ap)        : _ptr(ap._ptr)    {        ap._ptr = nullptr;    }    // 解引用操作符,返回所管理资源的引用    T& operator*()    {        return *_ptr;    }    // 成员访问操作符,返回所管理资源的指针    T* operator->()    {        return _ptr;    }private:    T* _ptr;  // 指向动态分配的资源的指针};

这段代码是一个简化版的 auto_ptr 类的实现,用于演示 auto_ptr 的基本工作原理。它是一个模板类,可以管理任意类型的动态分配的内存资源。

⭕该类包含了以下成员函数和成员变量:

构造函数:接受一个指向动态分配的资源的指针,并将其存储在私有成员变量 _ptr 中。析构函数:在对象销毁时释放资源,即调用 delete 操作符删除 _ptr 指向的内存。拷贝构造函数:用于管理权转移,将另一个 auto_ptr 对象的资源转移到当前对象中,并将原对象的指针置为空。operator*:用于解引用 auto_ptr 对象,返回所管理资源的引用。operator->:用于访问 auto_ptr 所管理资源的成员。

??再次提醒当一个 auto_ptr 对象转移所有权后,原来的对象将变为一个空指针。这可能导致程序出现意外的行为,因此需要谨慎使用

二、std::unique_ptr

?std::unique_ptr官方文档
在这里插入图片描述

1. 简介

std::unique_ptr 是 C++11 中引入的一种智能指针,它是一个轻量级的、不可拷贝的指针类型。与传统的裸指针不同,std::unique_ptr 通过 RAII 的方式来管理动态分配的内存资源,从而实现自动资源释放和防止内存泄漏

使用 std::unique_ptr 可以避免手动管理动态分配的内存资源,因为 std::unique_ptr 自身就拥有资源的所有权,当 std::unique_ptr 被销毁时,它所管理的资源也会被自动释放。这使得代码更加简洁、安全和易于维护

std::unique_ptr 有以下几个主要特点:

不支持拷贝和赋值操作,即不能直接复制或赋值一个 std::unique_ptr 对象,只能通过移动语义或者 std::move 函数来转移资源的所有权;在默认情况下,std::unique_ptr 使用 delete 操作符来释放所管理的资源,但也可以通过自定义删除器来实现对资源的自定义释放操作;支持使用 lambda 表达式来实现自定义删除器,从而更加灵活地管理资源。

2. 使用示例

下面是一个简单的示例,演示了 std::unique_ptr 的基本使用方法:

#include <iostream>#include <memory>int main(){    // 使用 std::unique_ptr 来管理动态分配的 int 类型对象    std::unique_ptr<int> uptr(new int(42));    // 解引用操作符,返回所管理资源的引用    std::cout << *uptr << std::endl;    // 成员访问操作符,返回所管理资源的指针    int* p = uptr.get();    std::cout << *p << std::endl;    // 试图复制或赋值 unique_ptr 对象会编译错误    // std::unique_ptr<int> uptr2 = uptr; // Error    // 转移资源所有权    std::unique_ptr<int> uptr2 = std::move(uptr);    std::cout << *uptr2 << std::endl;    return 0;}

输出结果为

424242

??注意:由于 std::unique_ptr 是一个模板类,可以管理任意类型的动态分配的内存资源,因此使用时需要显式指定模板参数。另外,对于数组的动态分配内存资源的管理,建议使用 std::unique_ptr 的数组版本 std::unique_ptr<T[]>

3. C++模拟实现

template<class T>class unique_ptr{public:    // 构造函数,接受一个裸指针作为参数    unique_ptr(T* ptr)        :_ptr(ptr)    {}    // 析构函数,释放资源    ~unique_ptr()    {        if (_ptr)        {            cout << "delete:" << _ptr << endl;            delete _ptr;        }    }    // 重载解引用操作符,返回资源的引用    T& operator*()    {        return *_ptr;    }    // 重载成员访问操作符,返回资源的指针    T* operator->()    {        return _ptr;    }    // 防止拷贝和赋值    // C++11思路:直接将拷贝构造函数和赋值运算符声明为删除函数    unique_ptr(const unique_ptr<T>& up) = delete;    unique_ptr<T>& operator=(const unique_ptr<T>& up) = delete;    // 防止拷贝和赋值    // C++98思路:只声明不实现,但是用的人可能会在外部强行定义,所以再加一条,声明为私有    // private:    // unique_ptr(const unique_ptr<T>& up);    // unique_ptr<T>& operator=(const unique_ptr<T>& up);private:    T* _ptr;};

?这段代码实现了一个简化版的 unique_ptr 类,具有管理动态资源的能力,并防止了拷贝和赋值操作。注释中详细解释了每个函数的作用和实现原理,以及两种防止拷贝和赋值的方式(C++11 和 C++98 思路)

温馨提示

感谢您对博主文章的关注与支持!另外,我计划在未来的更新中持续探讨与本文相关的内容,会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!
在这里插入图片描述


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/85871.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 姐姐被害难产身亡后,我重生七零杀疯了惊天黑幕_杨雪林建志诚未删减_小说后续在线阅读_无删减免费完结_
  • 终章小说鹿言裴禹完结篇(爱你的事当做秘密)已更新+延伸(鹿言裴禹)清爽版
  • 妻子用十根钢钉迎接女儿回家,我不要她了完结全文_瑶瑶裴璇苏大强完结全文_小说后续在线阅读_无删减免费完结_
  • (陈晃陈娩)姐姐,是我的错陈晃陈娩延伸在线下载无广告章节清单
  • 梧桐影里别经年(姜岳霆裴智秀)_梧桐影里别经年(姜岳霆裴智秀)
  • 被污蔑偷换学霸高考成绩后,我杀疯了一口气看完_周启书瑶快手热门_小说后续在线阅读_无删减免费完结_
  • 黑月光钓遍全界男主都到我碗里来(桑泠贺苏言)_黑月光钓遍全界男主都到我碗里来(桑泠贺苏言)
  • 宋伊人骆屿小说完本章节前文+全篇阅读(暗香浮动月黄昏)连载中
  • 夫君是太监又怎么了?(安生阿梅)_夫君是太监又怎么了?(安生阿梅)
  • 穿成资本家大小姐,卷走家产去下乡(宋夕颜宋佳佳)全书免费_(宋夕颜宋佳佳)穿成资本家大小姐,卷走家产去下乡后续(宋夕颜宋佳佳)
  • 全书浏览他装失忆骗我三年,我装失忆送他进去(沈砚司苏念苏虞宁)_他装失忆骗我三年,我装失忆送他进去(沈砚司苏念苏虞宁)全书结局
  • 重生团宠京圈皇太女是满级大佬(桑柠秦妄)全书浏览_重生团宠京圈皇太女是满级大佬全书浏览

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1