更多课程 选择中心

C/C++培训
达内IT学院

400-996-5531

C++ shared_ptr和动态数组

  • 发布:C++培训
  • 来源:学习笔记
  • 时间:2020-07-31 14:32

std::shared_ptr智能指针是c++11一个相当重要的特性,可以极大地将开发者从资源申请/释放的繁重劳动中解放出来,然而直到c++17前std::shared_ptr都有一个严重的限制,那就是它并不支持动态数组:

#include <memory>

std::shared_ptr<int[]> sp1(new int[10]()); // 错误,c++17前不能传递数组类型作为shared_ptr的模板参数

std::unique_ptr<int[]> up1(new int[10]()); // ok, unique_ptr对此做了特化

std::shared_ptr<int> sp2(new int[10]()); // 错误,可以编译,但会产生未定义行为,请不要这么做

sp1错误的原因很明显,然而sp2的就没有那么好找了,究其原因,是因为std::shared_ptr对非数组类型都使用delete p释放资源,显然这对于new int[10]来说是不对的,对它应该使用delete [] p。

其实c++17前的解决方案并不复杂,我们可以借助std::default_delete,它用于提供对应类型的正确的delete操作:

std::shared_ptr<int> sp3(new int[10](), std::default_delete<int[]>());

现在我们提供了正确的delete操作,可以放心地使用了。

不过这么做的缺点也是很明显的:

我们想管理的值是int[]类型的,然而事实上传给模板参数的是int

需要显示提供delete functor

不能使用std::make_shared,无法保证异常安全

c++17前shared_ptr未提供opreator[],所以当需要类似操作时不得不使用sp3.get()[index]的形式

事实上共享一片连续分配内存的需求是极为常见的,所以为了修正上述缺陷,c++17以及即将推出的c++2a对std::shared_ptr做了完善。

先说c++17的改进,shared_ptr增加了opreator[],并可以使用int[]类的数组类型做模板参数,所以sp3的定义可以简化了:

std::shared_ptr<int[]> sp3(new int[10]());

对于访问分配的空间,可以将sp3.get()[index]替换为sp3[index]。看个具体的例子:

#include <iostream>

#include <memory>

int main()

{

std::shared_ptr<int[]> sp(new int[5]());

for (int i = 0; i < 5; ++i) {

sp[i] = (i+1) * (i+1);

}

for (int i = 0; i < 5; ++i) {

std::cout << sp[i] << std::endl;

}

}

我们分配一个有5个int元素的动态数组,然后分别赋值1-5的平方,然后输出:

g++ -Wall -std=c++17 test.cpp

./a.out

使用被极大得简化了,然而还是有点问题,那就是无法使用std::make_shared,而我们除非指定自己的delete functor,否则我们应该尽量使用std::make_shared。

所以c++20对此做了改进:

auto up2 = std::make_unique<int[]>(10); // 从c++14开始,分配一个管理有10个int元素的动态数组的unique_ptr

// c++2a中你可以这样写,与上一句相似,只不过返回的是shared_ptr

auto sp3 = std::make_shared<int[]>(10);

在我的编译器上(GCC 8.2.1)还不能支持这一特性,所以很遗憾得不能提供演示了。

不过等c++2a(很可能就叫c++20)发布后std::shared_ptr就能安全而便捷地管理动态数组了。

当你还在担心能否就业时,达内学员提前被企业录取;当你转辗于各大招聘会时,达内学员收到了高薪offer;当你在各大招聘网站投递简历时,达内学员中有人一毕业进入五百强名企。所以选择很重要。找C++培训班,选达内就对了。

文章来源:公众号编程珠玑,版权声明:转载文章来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:C/C++返回内部静态成员的陷阱
下一篇:C语言创建windows窗口实例

C语言创建windows窗口实例

C++回调函数是什么?

C++ shared_ptr和动态数组

C语言有哪些关键词,C语言44个关键词大全

Copyright © 2023 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省