shared_ptr 与 make_shared 初识
#define _ALLOCATE_MAKE_SHARED( \ TEMPLATE_LIST, PADDING_LIST, LIST, COMMA, X1, X2, X3, X4) \ template<class _Ty COMMA LIST(_CLASS_TYPE)> inline \ shared_ptr<_Ty> make_shared(LIST(_TYPE_REFREF_ARG)) \ { /* make a shared_ptr */ \ _Ref_count_obj<_Ty> *_Rx = \ new _Ref_count_obj<_Ty>(LIST(_FORWARD_ARG)); \ shared_ptr<_Ty> _Ret; \ _Ret._Resetp0(_Rx->_Getptr(), _Rx); \ return (_Ret); \ } \
C++11:
shared_ptr:智能指针共享型
make_shared是一个模板函数,std::make_shared 以上是源码。
使用示例:
class A{
public:
A(int a_):a(a_);
~A();
private:
int a;
}
shared_ptr<A> obj_a = make_shared<A>(3);
make_shared在动态内存中申请一块A类对象内存 并初始化这个对象。然后返回一个shared_ptr智能指针指向这个对象,由shared_ptr管理动态内存
make_shared构造对象的时候最多带10个参数
shared_ptr 记录引用内存对象做一个计数(复制,拷贝等计数+1),当智能指针析构时计数-1 计数为0时没有指针指向这一段内存,此时释放这段内存。
构造函数
shared_ptr<T> sp;空的shared_ptr,可以指向T类型的对象 引用计数 = 0
shared_ptr<T> sp(new T());shared_ptr指向T类型的对象 引用计数=1
shared_ptr<T> sp(p1) ; sp与p1 共同管控同一段内存 引用计数=2
shared_ptr<T[]> sp;C++17之后支持
shared_ptr<T[]> sp(new T[5]{}); C++17之后支持
shared_ptr<T> sp(NULL,D()); C++17之后支持 利用仿函数,释放前调用。
shared_ptr<T> sp(new T(),D()) C++17之后支持 利用仿函数,释放前调用。
= 赋值
shared_ptr<T> p1(new T(1)); shared_ptr<T> p2(new T(2)); p1 = p2; T(1) 的引用计数-1,被释放 T(2)的引用计数=2
p1 = NULL 主动释放计数-1 被释放
reset
p1.reset(); 重置智能指针,所有的引用计数-1
p1.reset(new T(7)); 原有的引用计数-1,重置智能指针,指向新的T(7)
p1.reset(p1,D()); 指定删除器
swap; 交换
shared_ptr 交叉引用导致内存泄漏 可以使用weak_ptr配合使用,不会引起计数+1 -1 ; 允许共享指针赋值给weak_ptr,不支持 * 和 ->的使用;
如果要使用weak_ptr可以使用 .lock()提升为共享指针去构造一个新的shared_ptr执行 *和 ->的操作
dynamic_pointer_cast:
class A{
//.....
}
class B:public A{
//...
}
void func(const shared_ptr<A>& a_test ){
auto msg = std::dynamic_pointer_cast<B>(a_test); //a_test拥有 B 类对象的所有资源
}
A * a_p = new B();
shared_ptr<A> p(a_p );
func(p);
排查性的独享智能指针
unique_ptr取代了 auto_ptr
不允许 p1=p2赋值操作 ; 不允许 unique_ptr<string> p3(p4) 复制构造;但是可以 p1 = std::move(p2) 将p2管理的一段内存交给p1,p2此时被清除置空
依旧不能两个智能指针指向同一段内存
使用容器管理是安全的(禁止了 = 操作)
unique_ptr构造:
unique_ptr<T> up; 空的unique_ptr,可以指向T类型的对象
unique_ptr<T> up(new T());unique_ptr,指向T类型的对象,或者 up = std::move(p1)
unique_ptr<T[]> up;
unique_ptr<T[]> up(new T[5]); 在up对象被释放的时候 会调用5次delete[] T 析构 ;auto_ptr 不可以
unique_ptr<T,DestructFunc>up(); 利用仿函数,释放前调用。
struct DestructFunc{
void operator()(T *p){
p->func();
delete p;
}
}
unique_ptr<T> up(new T()); 可以主动释放 up = NULL;
C++98 :
auto_ptr智能指针,利用智能指针对象在失效的时候自动释放,去delete 绑定的指针对象
注意 1.不要定义为全局的:全局的对象要在程序结束才会释放,那就是去了智能的意义了。
2.不要定义为智能指针 为指针。同样多出了一个指针,智能指针也失去意义了
不要将一个智能指针赋值给一个同类型的智能指针对象,除非你真正知道带来的后果是什么
auto_ptr<string> p1( new string("aaaaaa"));
auto_ptr<string> p1(new string("bbbbbbbbb"));
p1 = p2;
reset():清空原有管理的,重新设置一个新的
release():交出当前管理的,清空
p1内部的指针会被释放(reset()),p2会交出(release())自己管理的内存,交给p1管理
auto_ptr陷阱 不能把同一段内存交给多个智能指针管理:如果其中一个已经被释放,当时用另外一个的时候就会崩溃
如果智能指针被放进了vector<auto_ptr<string>> A ,当执行 A[0] = A[1] A[1]内部管理的内存被释放,直接崩溃
留言评论
暂无留言