C++ primer 薄片系列之 智能指针
2017-11-02 14:35
204 查看
shared_ptr
引用次数和交换操作std::shared_ptr<A> a(new A); std::cout << a.use_count() << std::endl; // 输出 1 std::shared_ptr<A> b; std::cout << b.use_count() << std::endl; // 输出 0 a.swap(b); std::cout << a.use_count() << std::endl; // 输出 0 std::cout << b.use_count() << std::endl;// 输出 1
reset 相关操作
std::shared_ptr<int> b(new int); b.reset() //reset释放对象 b.reset(new int) //b 指向新的对象 b.reset(q,d)//调用d 而不是delete 去释放q std::shared_ptr<A> a(new A); a.reset(new A, [](A*){std::cout << "I do nothing" << std::endl;});// 使用新的lambda表达式而不是delete去释放,这里a的reset后的新对象,并没有释放
unique_ptr
它的reset 没有shared_ptr中的reset(p,d)操作, 即不能在reset 函数中传递删除器,只能在实例化模板时提供删除器std::shared_ptr<A> a; if(!a) { std::cout << "a is empty" << std::endl; } std::unique_ptr<A> b(new A); a.reset(b.release());// b放弃对指针的控制权,返回指针给 a.reset做参数,b置空 if(!b) { std::cout << "b is empty" << std::endl; } std::unique_ptr<A> b(new A); b.reset(nullptr);//OR b.reset() 均可使b置空 if(!b) { std::cout << "b is empty" << std::endl; } std::unique_ptr<A> b(new A, [](A*){std::cout << "我代替了delete操作" << std::endl;}); // 错误, unique_ptr reset没有重载这个函数 std::unique_ptr<A,void(*)(A*)> s(new A, [](A*){std::cout << "I do nothing" << std::endl;});// 只能在unique_ptr实例化的时候,提供模板参数,这里采用了lambda表达式。也可以使用函数 void delFunc(A *) { std::cout << "I do nothing" << std::endl; } std::unique_ptr<A,decltype(delFunc)*> s2(new A,delFunc);
—管理动态数组
unique_ptr<A[]> up(new A[]); up在作用域结束后,会自动调用delete[] ,释放动态数组。 访问动态数组中的元素时,可以直接 up[i] 的形式 shared_ptr则必须制定动态数组删除器 shared_ptr< A > sh(new A[10]); //严重bug std::shared_ptr< A> sp(new A[10],[](A *p){delete[] p;});//必须定义删除器 访问动态数组的元素时,只能以 *(sh.get()+i)的方式获取 sh内置动态数组中的元素
weak_ptr
w.use_count()w.expired() use_count == 0 时为true,否则false
w.lock() expired 为true时返回空shared_ptr否则返回指向w的对象的shared_ptr
避免循环引用
class B; class A { public: shared_ptr<B> pb; }; class B { public: shared_ptr<A> pa; }; { shared_ptr<A> a(new A); shared_ptr<B> b(new B); a->pb = b;//b.use_count() == 2 b->pa = a;//a.use_count() == 2 } a和b离开作用域, 释放B,导致b的引用次数除掉1,此时b所指的内存引用次数为2-1 = 1,同样a所指向的内存的引用次数也是2-1 = 1,从 a和b所指向的内存不能析构,形成了内存泄露。 此时需要把 pa换成 weak_ptr<A>, pb 换成 weak_ptr<B>, OK了。
Allocator
这玩意存在的理由在于, new的负担太重了,它完成了内存分配和对象构造两件事情。为了分离这两件事情,所以就有了它。class A { A(){} ~A(){} }; std::allocator<A> alloc; auto p = alloc.allocate(10); // 此时A的构造函数不会被调用 auto q = p; alloc.construct(q++); while (q != p) { alloc.destroy(--q); } alloc.deallocate(p, 10); std::allocator<A> alloc; auto p = alloc.allocate(10); 拷贝和填充未初始化内存的算法 std::uninitialized_copy(s.begin(),s.end(), p); // 调用A的拷贝构造函数 std::uninitialized_copy_n(s.begin(), 2, p); // 拷贝构造2个A 到p A data; std::uninitialized_fill(p,p+2, data);//填充data的拷贝到原始内存 std::uninitialized_fill_n(p,2, data);
相关文章推荐
- 读C++ Primer 之智能指针
- 实战c++中的智能指针unique_ptr系列-- unique_ptr的get_deleter方法(自定义删除器)
- 实战c++中的智能指针unique_ptr系列--通过unique_ptr对shared_ptr进行初始化
- C++深度探索系列:智能指针(Smart Pointer) [二]
- 实战c++中的智能指针unique_ptr系列--通过unique_ptr对shared_ptr进行初始化
- C++ Primer 第四版中文 智能指针部分的一个小疑惑
- C++ Primer中智能指针的一个小疑惑,是书中的bug?
- 实战c++中的智能指针unique_ptr系列-- std::unique_ptr的构造(尽量使用C++14中的std::make_unique,而不是new)
- C++深度探索系列:智能指针(Smart Pointer) [一]
- 《C++ Primer》读书笔记第十二章-1-动态内存与智能指针
- C++ primer 读书笔记系列——(3)C++中的数组和指针
- C++深度探索系列:智能指针(Smart Pointer)
- 实战c++中的智能指针unique_ptr系列-- std::unique_ptr的构造(尽量使用C++14中的std::make_unique,而不是new)
- C++深度探索系列:智能指针(Smart Pointer) [二]
- 实战c++中的智能指针unique_ptr系列-- unique_ptr的get()赋给普通指针后的崩溃(其实是生命周期惹的祸)
- C++深度探索系列:智能指针(Smart Pointer) [一]
- 【Boost】系列03:内存管理之shared_ptr智能指针
- 实战c++中的智能指针unique_ptr系列-- unique_ptr的get()赋给普通指针后的崩溃(其实是生命周期惹的祸)
- 35、不一样的C++系列--智能指针
- 智能指针——《C++ Primer》 Chapter14