首页 > 其他分享 >26. 智能指针

26. 智能指针

时间:2024-11-16 17:47:31浏览次数:3  
标签:26 Person void 智能 shared ptr 指针

一、什么是智能指针

  当我们使用 new 关键字为指针变量动态申请内存时,但是使用完毕之后,我们可能会忘记使用 delete 关键字手动回收内存。因此,C++ 中提供了智能指针。当智能指针过期时,其析构函数将使用 delete 来释放内存。因此,如果将 new 返回的地址赋给智能指针对象,将无需手动释放内存,在智能指针过期时,这些内存将自动被释放。

  C++ 11 引入了 3 个智能指针类型:

  • std::unique_ptr<T>独占资源所有权的指针。也就是说,同时只有一个 unique_ptr 指向同一个对象,当这个 unique_ptr 被销毁时,指向的对象也随即被销毁。
  • std::shared_ptr<T>共享资源所有权的指针。多个 share_ptr 可以指向(关联)相同的对象,在内部采用计数机制来实现。当新的 shared_ptr 与对象关联时,引用计数增加 1。当 shared_ptr 超出作用域时,引用计数减 1。当引用计数变为 0 时,则表示没有任何 shared_ptr 与对象关联,则释放该对象。
  • std::weak_ptr<T>共享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期。

  要创建智能指针对象,必须包含头文件 memory,该文件模板定义。然后使用通常的模板语法来实例化所需类型的指针。所有的智能指针都有一个 explicit 构造函数,该构造函数将指针作为参数。因此不需要自动将指针转换为智能指针对象。

二、独占智能指针

  独占智能指针独占资源所有权的指针。也就是说,同时只有一个独占指针指向同一个对象,当这个独占指针被销毁时,指向的对象也随即被销毁。

  unique_ptr 指针的初始化方法如下:

unique_ptr<T> ptr(new T(args...));
unique_ptr<T> ptr = make_unique<T>(args...);
class Person
{
private:
    string name;
    int age;

public:
    Person(void);
    Person(string name, int age);

    ~Person(void);

    string getName(void) const;
    void setName(string name);
    int getAge(void) const;
    void setAge(int age);
};

Person::Person(void) 
{
    cout << "Person()" << endl;
}

Person::Person(string name, int age) : name(name), age(age) 
{
    cout << "Person(string name, int age)" << endl;
}

Person::~Person(void)
{
    cout << "~Person()" << endl;
}

string Person::getName(void) const
{
    return name;
}

void Person::setName(string name)
{
    this->name = name;
}

int Person::getAge(void) const
{
    return age;
}

void Person::setAge(int age)
{
    this->age = age;
}
#include <iostream>
#include <memory>

using namespace std;

int main(void) 
{
    unique_ptr<Person> p1(new Person("Sakura", 10));
    cout << "{name: " << (*p1).getName() << ", age: " << p1->getAge() << "}" << endl;

    unique_ptr<Person> p2 = make_unique<Person>("Sakura", 12);
    cout << "{name: " << (*p2).getName() << ", age: " << p2->getAge() << "}" << endl;
  
    // 重置智能指针,解除对原始内存的管理,重新指定指针管理的原始内存
    p1.reset(new Person("Mikoto", 14));
    cout << "{name: " << (*p1).getName() << ", age: " << p1->getAge() << "}" << endl;

    // 重置智能指针,解除对原始内存的管理
    p2.reset();
    p2 = make_unique<Person>("Shana", 15);
    cout << "{name: " << (*p2).getName() << ", age: " << p2->getAge() << "}" << endl;

    return 0;
}

  在 C++ 11 之前的版本,如果智能指针管理的数组内存时,需要手动指定删除函数。

int main(void) 
{
    // C++ 11 之前的版本,如果智能指针管理的数组内存时,需要手动指定删除函数
    // 需要在模板中指定第二个参数指定删除器的地址,使用函数指针即可
    typedef void (*func_ptr)(Person *);
    unique_ptr<Person, func_ptr> p1(new Person[5], [](Person *p) { delete[] p; });

    return 0;
}

unique_ptr 智能指针对象没有拷贝构造函数,也不能进行赋值操作和普通指针操作。

三、共享智能指针

  多个共享智能指针可以指向(关联)相同的对象,在内部采用计数机制来实现。当新的共享智能指针与对象关联时,引用计数增加 1。当共享智能指针超出作用域时,引用计数减 1。当引用计数变为 0 时,则表示没有任何共享指针与对象关联,则释放该对象。

  shared_ptr 指针的初始化方法如下:

shared_ptr<T> ptr(new T(args...));
shared_ptr<T> ptr = make_shared<T>(args...);
shared_ptr<T> ptr = ptr1;
#include <iostream>
#include <memory>

using namespace std;

int main(void) 
{
    shared_ptr<Person> p1(new Person("Sakura", 10));
    shared_ptr<Person> p2 = make_shared<Person>("Sakura", 12);
    shared_ptr<Person> p3 = p2;

    cout << "{name: " << (*p1).getName() << ", age: " << p1->getAge() << "}" << endl;
    cout << "{name: " << (*p2).getName() << ", age: " << p2->getAge() << "}" << endl;
    cout << "{name: " << (*p3).getName() << ", age: " << p3->getAge() << "}" << endl;

    cout << "p1 use_count(): " << p1.use_count() << endl;
    cout << "p2 use_count(): " << p1.use_count() << endl;
    cout << "p3 use_count(): " << p3.use_count() << endl;

    // 重置智能指针,解除对原始内存的管理,重新指定指针管理的原始内存
    p1.reset(new Person("Mikoto", 14));

    // 重置智能指针,解除对原始内存的管理
    p2.reset();
    p2 = make_shared<Person>("Shana", 15);
  
    cout << "{name: " << (*p1).getName() << ", age: " << p1->getAge() << "}" << endl;
    cout << "{name: " << (*p2).getName() << ", age: " << p2->getAge() << "}" << endl;
    cout << "{name: " << (*p3).getName() << ", age: " << p3->getAge() << "}" << endl;

    cout << "p1 use_count(): " << p1.use_count() << endl;
    cout << "p2 use_count(): " << p1.use_count() << endl;
    cout << "p3 use_count(): " << p3.use_count() << endl;
  
    return 0;
}

  在 C++ 11 之前的版本,如果智能指针管理的数组内存时,需要手动指定删除函数。

int main(void) 
{
    // C++ 11 之前的版本,如果智能指针管理的数组内存时,需要手动指定删除函数
    shared_ptr<Person> p1(new Person[5], [](Person *p) { delete[] p; });
    // 使用默认的删除函数
    shared_ptr<Person> p2(new Person[5], default_delete<Person[]>());

    return 0;
}

三、弱引用智能指针

  弱引用智能指针需要和共享指针一起使用,它不影响资源的生命周期。弱引用智能指针可以看作共享指针的的助手,它不管理共享指针内部的指针。弱引用智能指针没有重载运算符 *->,这是因为它不共享指针,也不能操作资源,所以它的构造不会增加引用计数,析构也不会减少引用计数,它的主要作用就是作为一个旁观者监视共享指针中管理的资源是否存在。

  weak_ptr 指针的初始化方法如下:

weak_ptr<T> ptr(const weak_ptr & x);
weak_ptr<T> ptr(const share_ptr & x);
weak_ptr<T> ptr = ptr1
int main(void) 
{
    // 如果智能指针管理的数组内存时,需要手动指定删除函数
    shared_ptr<Person> sp(new Person("Tom", 18));

    weak_ptr<Person> wp1;
    weak_ptr<Person> wp2(wp1);
    weak_ptr<Person> wp3(sp);
    weak_ptr<Person> wp4 = wp1;

    return 0;
}
class ClassA 
{
private:
    std::shared_ptr<ClassB> bptr;

public:
    void setB(std::shared_ptr<ClassB> b) 
    {
        bptr = b;
    }
};

class ClassB 
{
private:
    std::weak_ptr<ClassA> aptr;     // 使用弱引用避免循环引用

public:
    void setA(std::shared_ptr<ClassA> a)
    {
        aptr = a;
    }
};

标签:26,Person,void,智能,shared,ptr,指针
From: https://blog.csdn.net/flurry_heart/article/details/143805229

相关文章

  • SpringBoot游泳馆会员管理系统q26c5(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景与意义随着健康意识的提升,游泳馆作为重要的健身场所,其会员管理效率直接影响到顾客体验和经营效益。传统的会员管理方式存在信息记录不......
  • 【技术革新】哋它亢编程语言3.12版本:智能时代的新里程碑
    在技术的浪潮中,总有一些时刻标志着新时代的开始。今天,我们要探讨的“哋它亢编程语言”3.12版本,就是这样一个时刻。这个版本不仅带来了性能的飞跃,还引入了多项创新特性,为开发者提供了更广阔的舞台。3.12版本的亮点特性:性能的全面提升:哋它亢3.12版本在性能上进行了深度优化,无论......
  • 看过这个,你可能更了解指针一点(2)
    先来看下图你认为以下的打印的结果是什么?接下来,我们先来分析****在1中arr单独放在sizeof内表示整个数组,因此计算的为整个数组大小。即6乘1得到61的答案为6****在2中arr没有被单独放在sizeof中,arr此时表示数组首元素的地址,+0则表示计算的是第一个元素地址的大小,其结......
  • C/C++ 指针
    指针内存分类:运行内存存储命令注意当我们程序运行时系统会在运行内存中开启一片空间给当前程序使用32位机最多给一个程序开启4G的运行内存,64位8G将开启的内存以1字节为单位进行划分,每个字节的内存都有其对应的地址编号这些地址编号也是数据,其数据类型为指针......
  • 【IEEE出版、八大高校联合举办、稳定EI检索】第四届人工智能与智能制造国际研讨会(AIIM
    第四届人工智能与智能制造国际研讨会(AIIM2024)The4thInternationalSymposiumonArtificialIntelligenceandIntelligentManufacturing2024年12月20-22日中国成都重要信息大会官网:www.isaiim.com大会时间:2024年12月20-22日大会地点:中国-成都二轮截......
  • AI Agent 的技术原理:解密智能代理的“大脑“
    目录引言AIAgent的核心架构1.大语言模型(LLM):AIAgent的"大脑"2.规划模块:制定行动蓝图3.记忆模块:存储和检索信息4.工具使用模块:扩展Agent能力AIAgent的工作流程技术挑战与未来发展结语引言在 AIAgent技术概述:开启智能时代的新篇章,对AIAgent进行了......
  • 基于springboot的多功能智能手机阅读APP设计与实现
    前言时代在飞速进步,每个行业都在努力发展现在先进技术,通过这些先进的技术来提高自己的水平和优势,多功能智能手机阅读APP当然不能排除在外。多功能智能手机阅读APP是在实际应用和软件工程的开发原理之上,运用java语言以及SpringBoot框架进行开发。首先要进行需求分析,分析出......
  • 智能驾驶SoC芯片行业竞争格局分析
    车载SoC芯片行业竞争格局(智能驾驶篇)&nbsp;&nbsp;通常情况下,车企不同的车型平台有不同的市场定位,市场定位又决定了车型的售价区间,不同售价的车型对功能配置的价格敏感度也存在差异。在智能驾驶功能配置上,不同市场定位车型(不同价位车型)的智能驾驶方案对主控SoC芯片也存在......
  • 人工智能同样也会读死书----“过拟合”
    上一篇:《“嵌入”在大语言模型中是解决把句子转换成向量表示的技术》序言:我们常常会说某某人只会“读死书”,题目稍微变一点就不会做了。这其实是我们人类学习中很常见的现象。可是你知道吗?人工智能其实更容易“读死书”。不过在人工智能领域,我们有个听起来高大上的说法,叫“过拟......
  • AI大模型实战:打造银行智能营销助手:大模型助力精准营销的8大优势
    在金融科技快速发展的时代,银行的业务模式和客户需求都发生了巨大变化。为了应对日益激烈的市场竞争,银行必须依托先进技术,提升客户服务水平和营销效率。银行智能营销助手应运而生,它通过结合知识图谱和大模型(LLM),帮助银行精确获取客户信息、分析市场需求、定制个性化营销方案,为......