C++11 关于shared_ptr的用法

偏爱风流 2014-01-13 04:19:41
一些关于shared_ptr大部分也只阐述了其最基本的用法。
但当有大量的指针需要new时不免也会产生过多的碎片,自定义分配器是一个好的解决方法。
参考了下C++11的标准:
template<class Y, class D> shared_ptr(Y* p, D d);
template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
template <class D> shared_ptr(nullptr_t p, D d);
template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
8 Requires: p shall be convertible to T*. D shall be CopyConstructible. The copy constructor and
destructor of D shall not throw exceptions. The expression d(p) shall be well formed, shall have
well defined behavior, and shall not throw exceptions. A shall be an allocator (17.6.3.5). The copy
constructor and destructor of A shall not throw exceptions.
9 Effects: Constructs a shared_ptr object that owns the object p and the deleter d. The second and
fourth constructors shall use a copy of a to allocate memory for internal use.
10 Postconditions: use_count() == 1 && get() == p.
11 Throws: bad_alloc, or an implementation-defined exception when a resource other than memory
could not be obtained.
12 Exception safety: If an exception is thrown, d(p) is called.

依着理解应该是这么回事:

template<typename T>
class M_Alloc
{
//TODO
//对分配器的要求没有细看,跳转的太多了。
};
template<typename T>
class M_Delete
{
//TODO
};
int* p = nullptr;
M_Delete d;
M_Alloc a;
std::shared_ptr<int,M_Delete,M_Alloc>(p,d,a);

不知道如此使用是否正确。
PS:boost::shared_ptr 没有用过
...全文
242 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
偏爱风流 2014-01-13
  • 打赏
  • 举报
回复
引用 5 楼 ganpengjin1 的回复:
[quote=引用 4 楼 lx458004975 的回复:] [quote=引用 3 楼 ganpengjin1 的回复:] [quote=引用 2 楼 lx458004975 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] 恩,处理分配器,这个得小心使。
水区经常看到你哈。 分配器是有点麻烦,A shall be an allocator (17.6.3.5). 这一跳过去都是表,都不想看下去了。[/quote] 不用去写那个Alloc,不用管,直接用默认的Allocate就好了,你自己写搞不好出大问题。 shared_ptr<your_Date_Type >就行了。[/quote] 这不DD有点疼了嘛,就整一下玩玩。游戏中很多的基本上都是自己的分配器,缺省的分配器导致效率下降。[/quote] 那你去模仿其它的分配器自己写一个,应该问题不大。[/quote] 分配器倒是会弄,主要是确定下这个做法,以前也没去看标准。
漫步者、 2014-01-13
  • 打赏
  • 举报
回复
引用 4 楼 lx458004975 的回复:
[quote=引用 3 楼 ganpengjin1 的回复:] [quote=引用 2 楼 lx458004975 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] 恩,处理分配器,这个得小心使。
水区经常看到你哈。 分配器是有点麻烦,A shall be an allocator (17.6.3.5). 这一跳过去都是表,都不想看下去了。[/quote] 不用去写那个Alloc,不用管,直接用默认的Allocate就好了,你自己写搞不好出大问题。 shared_ptr<your_Date_Type >就行了。[/quote] 这不DD有点疼了嘛,就整一下玩玩。游戏中很多的基本上都是自己的分配器,缺省的分配器导致效率下降。[/quote] 那你去模仿其它的分配器自己写一个,应该问题不大。
偏爱风流 2014-01-13
  • 打赏
  • 举报
回复
引用 3 楼 ganpengjin1 的回复:
[quote=引用 2 楼 lx458004975 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] 恩,处理分配器,这个得小心使。
水区经常看到你哈。 分配器是有点麻烦,A shall be an allocator (17.6.3.5). 这一跳过去都是表,都不想看下去了。[/quote] 不用去写那个Alloc,不用管,直接用默认的Allocate就好了,你自己写搞不好出大问题。 shared_ptr<your_Date_Type >就行了。[/quote] 这不DD有点疼了嘛,就整一下玩玩。游戏中很多的基本上都是自己的分配器,缺省的分配器导致效率下降。
漫步者、 2014-01-13
  • 打赏
  • 举报
回复
引用 2 楼 lx458004975 的回复:
[quote=引用 1 楼 ganpengjin1 的回复:] 恩,处理分配器,这个得小心使。
水区经常看到你哈。 分配器是有点麻烦,A shall be an allocator (17.6.3.5). 这一跳过去都是表,都不想看下去了。[/quote] 不用去写那个Alloc,不用管,直接用默认的Allocate就好了,你自己写搞不好出大问题。 shared_ptr<your_Date_Type >就行了。
偏爱风流 2014-01-13
  • 打赏
  • 举报
回复
引用 1 楼 ganpengjin1 的回复:
恩,处理分配器,这个得小心使。
水区经常看到你哈。 分配器是有点麻烦,A shall be an allocator (17.6.3.5). 这一跳过去都是表,都不想看下去了。
漫步者、 2014-01-13
  • 打赏
  • 举报
回复
恩,处理分配器,这个得小心使。
智能指针 智能指针shared_ptr的⽤法 的⽤法   为了解决C++内存泄漏的问题,C++11引⼊了智能指针(Smart Pointer)。   智能指针的原理是,接受⼀个申请好的内存地址,构造⼀个保存在栈上的智能指针对象,当程序退出栈的作⽤域范围后,由于栈上的变 量⾃动被销毁,智能指针内部保存的内存也就被释放掉了(除⾮将智能指针保存起来)。   C++11提供了三种智能指针:std::shared_ptr, std::unique_ptr, std::weak_ptr,使⽤时需添加头⽂件。   shared_ptr使⽤引⽤计数,每⼀个shared_ptr的拷贝都指向相同的内存。每使⽤他⼀次,内部的引⽤计数加1,每析构⼀次,内部的引⽤ 计数减1,减为0时,删除所指向的堆内存。shared_ptr内部的引⽤计数是安全的,但是对象的读取需要加锁。 1. shared_ptr的基本⽤法 初始化   可以通过构造函数、std::make_shared辅助函数和reset⽅法来初始化shared_ptr: #include "stdafx.h" #include #include #include using namespace std; class Person { public: Person(int v) { value = v; std::cout << "Cons" <shared_ptr p1(new Person(1));// Person(1)的引⽤计数为1 std::shared_ptr p2 = std::make_shared(2); p1.reset(new Person(3));// ⾸先⽣成新对象,然后引⽤计数减1,引⽤计数为0,故析构Person(1) // 最后将新对象的指针交给智能指针 std::shared_ptr p3 = p1;//现在p1和p3同时指向Person(3),Person(3)的引⽤计数为2 p1.reset();//Person(3)的引⽤计数为1 p3.reset();//Person(3)的引⽤计数为0,析构Person(3) return 0; }   注意,不能将⼀个原始指针直接赋值给⼀个智能指针,如下所⽰,原因是⼀个是类,⼀个是指针。 std::shared_ptr p4 = new int(1);// error   reset()包含两个操作。当智能指针中有值的时候,调⽤reset()会使引⽤计数减1.当调⽤reset(new xxx())重新赋值时,智能指针⾸先是⽣ 成新对象,然后将就对象的引⽤计数减1(当然,如果发现引⽤计数为0时,则析构旧对象),然后将新对象的指针交给智能指针保管。 获取原始指针   std::shared_ptr p4(new int(5)); int *pInt = p4.get(); 指定删除器   智能指针可以指定删除器,当智能指针的引⽤计数为0时,⾃动调⽤指定的删除器来释放内存。std::shared_ptr可以指定删除器的⼀个原 因是其默认删除器不⽀持数组对象,这⼀点需要注意。   2. 使⽤shared_ptr需要注意的问题   但凡⼀些⾼级的⽤法,使⽤时都有不少陷阱。 不要⽤⼀个原始指针初始化多个shared_ptr,原因在于,会造成⼆次销毁,如下所⽰: int *p5 = new int; std::shared_ptr p6(p5); std::shared_ptr p7(p5);// logic error 不要在函数实参中创建shared_ptr。因为C++的函数参数的计算顺序在不同的编译器下是不同的。正确的做法是先创建好,然后再传 ⼊。 function(shared_ptr(new int), g()); 禁⽌通过shared_from_this()返回this指针,这样做可能也会造成⼆次析构。 避免循环引⽤。智能指针最⼤的⼀个陷阱是循环引⽤,循环引⽤会导致内存泄漏。解决⽅法是AStruct或BStruct改为weak_ptr。 struct AStruct; struct BStruct; struct AStruct { std::shared_ptr bPtr; ~AStruct() {

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧