【C++ Primer 学习札记】使用new或者make_shared创建shared_ptr智能指针

《C++ Primer》P400

为了更容易(同时更安全)地使用动态内存,新的标准提供了智能指针(smart pointer)类型来管理动态对象。

智能指针的行为类似常规指针,重要的区别是它负责自动释放所指向的对象。

shared_ptr允许多个指针指向同一个对象

 创建并初始化一个shared_ptr智能指针的方式有四种:

1.默认初始化

2.make_shared

3.new返回的指针

4.其他类型的资源的指针(非动态内存)

 

 

1.默认初始化

shared_ptr<int> p;//可以指向int的一个空指针,指针值为空

 

2.make_shared

《C++ Primer》P401

此函数再动态内存中分配一个对象,使用args初始化此对象,返回一个指向此对象的shared_ptr

调用形式:make_shared<T>(args)

这里的args可以是空、字面值常量、变量、能与T类型的某个构造函数相匹配的参数列表等。

1)空

shared_ptr<int> p0=make_shared<int>();//指向一个默认值初始化的int对象,此对象值为0

2)字面值常量 

shared_ptr<int> p1=make_shared<int>(42);//指向一个值为42的int

3)变量

int a = 10;
shared_ptr<int> p2=make_shared<int>(a);//使用a初始化一个动态分配的类型为int的对象,注意这个对象和a不是同一个对象

 注意:这个对象和a不是同一个对象,这个对象是make_shared函数在动态内存中分配出来的一个对象,使用a进行值初始化,所以这个对象的值和a的值是相等的,但不是同一块内存!!!

 

4)能与T类型的某个构造函数相匹配的参数列表

shared_ptr<int> p3=make_shared<string>(10,'9');//指向一个值为“9999999999”的string

 

3.new返回的指针

我们可以用new返回的指针来直接初始化智能指针:

shared_ptr<int> p(new int(42));//p指向一个值为42的int对象

注意:接受指针参数的智能指针构造函数是explicit的,因此我们不能将一个内置指针隐式转换为一个智能指针,必须使用直接初始化形式!!!

shared_ptr<int> p = new int(42));//错误,必须使用直接初始化
//error C2440: “初始化”: 无法从“int *”转换为“std::shared_ptr<int>”,普通指针不能直接赋值给智能指针

 

4.其他类型的资源的指针(非动态内存)

《C++ Primer》P412

默认情况下,一个用来初始化智能指针的普通制作必须指向动态内存,因为智能指针默认使用delete释放它所关联的对象。

当然,我们可以将智能指针绑定到一个指向其他类型的资源的指针上,但是,为了这样做,必须提供自己的操作来替代delete

默认使用delete,可以将普通指针绑定到智能指针上。智能指针由普通指针值初始化,prob.get()的值等于&a 和pb的值

int a = 10;
int *pb = &a;//普通指针,指向a对象
std::shared_ptr<int> ptrb(&a);//默认使用delete 
std::shared_ptr<int> ptrb(pb);//默认使用delete 

 这里是因为我使用的是内置类型int的指针,默认delete刚好可以释放int类型,如果是其他类型的资源,必须加上自定义的删除器

所以,完整的写法应该由如下所示:

int a = 10;
int *pb = &a;//普通指针,指向a对象
std::shared_ptr<int> ptrb(&a, [](int *x) {delete x; });//定义了lambda作为删除器
std::shared_ptr<int> ptrb(pb,[](int *x) { delete x; });//定义了lambda作为删除器

这里的lambda表达式  [](int *x) { delete x; }  等价于 delete

 

如果使用的string类型的数组的指针(也就是string*指针)创建shared_ptr,则:

string *pia = new string[10];
//delete[] pia;//正确,当 new 一个有析构函数的对象数组的时候 必须要用 delete[]删除
//delete pia;//错误

shared_ptr<string>sp(pia, [](string *p) {delete[] p; });//正确
//shared_ptr<string>sp(pia);//错误
//shared_ptr<string>sp(pia, [](string *p) {delete p; });//错误

 这里的lambda表达式  [](string *p) { delete[] x; }  作为string*类型的删除器,

换句话说,这个删除器能够完成对shared_ptr中保存的指针进行释放操作

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用shared_ptr时,可以通过判断指针是否为空来确定是否指向有效的对象。在C++中,可以使用if语句和逻辑运算符来进行空判断。 引用和引用是两个示例源程序,演示了如何在使用shared_ptr时进行空判断。在示例中,如果shared_ptr为空指针,则输出相应的提示信息;如果shared_ptr不为空指针,则可以对指针进行解引用操作。 具体来说,在示例中,使用了if语句和逻辑运算符进行了空判断。例如,可以使用if(p1)来判断p1是否为空指针,如果为空指针,则输出提示信息;否则,可以对p1进行解引用操作,输出指向的值。 因此,通过if语句和逻辑运算符,可以在使用shared_ptr时进行空判断,以确保指针的有效性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [C++ Primer:判断shared_ptr是否为空智能指针?](https://blog.csdn.net/qq_34801642/article/details/105831225)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Effective Modern C++shared_ptr](https://download.csdn.net/download/weixin_38689551/14043292)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值