前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >智能指针模板类

智能指针模板类

作者头像
艰默
发布2023-02-26 10:53:55
6350
发布2023-02-26 10:53:55
举报
文章被收录于专栏:iDoitnow

智能指针是行为类似于指针的类对象,但这种对象还有其他功能。使用指针指向一块新申请的内存的过程中,有时忘记释放新申请的内存,导致内存泄漏。为了防止该问题的发生,C++提供了智能指针模板类。其思想就是将常规的指针变成一个类对象,该对象主要实现常规指针的功能,当该对象过期的时候,会自动调用其析构函数,在析构函数中完成内存释放的操作。

智能指针有auto_ptrunique_ptrshared_ptrweak_ptr(本章暂时不做详细介绍),其中auto_ptr在C++11中摒弃。

代码语言:javascript
复制
class A{...};
void fun()
{
    A* pa = new A;
    std::auto_ptr<A> p1 = new A;
    std::unique_ptr<A> p2 = new A;
    std::shared_ptr<A> p3 = new A;
    ...
    delete pa; //必须在pa过期之前释放分配的内存
    //delete p1;//不需要手动释放内存,在p1过期的时候,会自动调用其析构函数释放对应的内存块
    //delete p2;//不需要手动释放内存,在p2过期的时候,会自动调用其析构函数释放对应的内存块
    //delete p3;//不需要手动释放内存,在p3过期的时候,会自动调用其析构函数释放对应的内存块   
}

有关智能指针的注意事项

常规的指针在使用的过程中两个指针可能会指向同一个对象,这是不能接受的,因为程序在结束的时候会存在删除同一对象两次的问题,如下例:

代码语言:javascript
复制
std::string* ps (new std::string("abc"));
std::string* p1;
p1 = pa;  
...
delete ps;
delete pa;

针对上述问题,auto_ptrunique_ptr在常规指针的基础上增加了所有权的概念,对于特定对象,只有一个指针可以拥有它,这样只有拥有对象的智能指针才能删除该对象。

shared_ptr采用跟踪引用特定对象的智能计数(即引用计数)策略。例如,赋值的时候,计数加1,而指针过期的时候,计数减1,仅当最后一个指针过期的时候才调用delete

下面我们举个例子,看一下他们之间的区别。

代码语言:javascript
复制
auto_ptr<std::string> p1(new std::string("abc"));
auto_ptr<std::string> p2;
p2 = p1;    //p2接管string对象的所有权后,p1的所有权被剥夺,其不再指向有效数据,后面如果尝试调用p1,程序运行的时候则会导致程序core dumped

unique_ptr<std::string> p1(new std::string("abc"));
unique_ptr<std::string> p2;
p2 = p1;    //p2接管string对象的所有权后,p1的所有权被剥夺,其不再指向有效数据,后面如果尝试调用p1,则编译失败

shared_ptr<std::string> p1(new std::string("abc"));//引用计数器为1
shared_ptr<std::string> p2;
p2 = p1; //引用计数器为2
//在p1、p2过期的过程中,计数器相应减1,当最后一个智能指针过期的时候,调用修购函数时,将引用计数器降低到0,并释放对应的空间

从上面的例子可以看出unique_ptrauto_ptr最大的区别就在于当一个智能指针的所有权被剥夺后,若后面的程序要调用它的时候,unique_ptr直接在编译阶段就失败,将问题暴露出来,而auto_ptr编译阶段不会报错,在程序运行的时候出现异常,因此unique_ptr的安全性更高(编译阶段错误比程序崩溃更安全)。

相比auto_ptrunique_ptr另外一个优点就是它有一个可以用于数组的变体。我们知道deletenew配对,delete[]new[]配对,而auto_ptr中使用的是delete,而不是delete[],因此只能与new一起使用,不能与new[]一起使用。但unique_ptrdeletedelete[]两个版本,它可以与new一起使用,也可以与new[]一起使用。同样的,shared_ptr也支持与new一起使用,不支持new[]的使用。

:使用new分配内存时,可以使用auto_ptrunique_ptrshared_ptr;使用new[]分配内存时,不能使用auto_ptrshared_ptr,可以使用unique_ptr;不使用newnew[]分配内存时,不能使用unique_ptr

如何选择合适的指针

  • 程序要使用多个指向同一个对象的指针 使用shared_ptr
  • 程序不需要多个指向同一个对象的指针 使用unique_ptr
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iDoitnow 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 有关智能指针的注意事项
  • 如何选择合适的指针
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档