一 shared_ptr概述
shared_ptr 是C++11提供的一种智能指针类,它足够智能,可以在任何地方都不使用时自动删除相关指针,从而帮助彻底消除内存泄漏和悬空指针的问题。
它遵循共享所有权的概念,即不同的 shared_ptr 对象可以与相同的指针相关联,并在内部使用引用计数机制来实现这一点。
每个 shared_ptr 对象在内部指向两个内存位置:
1、指向对象的指针。
2、用于控制引用计数数据的指针。
共享所有权如何在参考计数的帮助下工作:
1、当新的 shared_ptr 对象与指针关联时,则在其构造函数中,将与此指针关联的引用计数增加1。
2、当任何 shared_ptr 对象超出作用域时,则在其析构函数中,它将关联指针的引用计数减1。如果引用计数变为0,则表示没有其他 shared_ptr 对象与此内存关联,在这种情况下,它使用delete函数删除该内存。
二 功能测试代码
#include <stdio.h>
#include <memory>
#include <iostream>
#include <functional>
using namespace std;
class A{
public:
A(int a):ma(a)
{
std::cout << "demoA 构造 "<<"ma:"<<ma<< std::endl;
}
A()
{
ma=100;
std::cout << "demoA 构造 "<<"ma:"<<ma<< std::endl;
}
void getA(){
std::cout << "测试a: " << ma<<std::endl;
}
~A()
{
std::cout<<"demoA 析构"<< "ma:"<<ma<<std::endl;
}
public:
int ma;
};
void deleter(A * x)
{
std::cout << "Custom Deleter\n";
delete[] x;
}
void myfunc(shared_ptr<A> ptmp)
{
return;
}
shared_ptr<A> myfunc1(shared_ptr<A>& ptmp)
{ // 如果参数为引用,则智能指针的引用计数不会增加
return ptmp;
}
int main(int argc, char *argv[])
{
//shared_ptr
//构建 2 个智能指针
std::shared_ptr<A> p1(new A(10));
std::shared_ptr<A> p2(p1);
//输出 p2 指向的数据
p1->getA();
p1.reset();//引用计数减 1,p1为空指针
if (p1) {
cout << "p1 不为空" << endl;
}
else {
cout << "p1 为空" << endl;
}
//以上操作,并不会影响 p2
p2->ma=11;
p2->getA();
//判断当前和 p2 同指向的智能指针有多少个
cout <<"p2 count: "<<p2.use_count() << endl;
p2.reset();
std::cout<<"-----------"<<endl;
std::shared_ptr<A> p3 = std::make_shared<A>(12); //建议使用这种方式初始化
p3->getA();
p3.reset(new A(13)); //会析构之前对象
p3->getA();
p3.reset();
cout <<" p3 count: "<<p3.use_count() << endl;
std::cout<<"-----------"<<endl;
//返回值与传参
std::shared_ptr<A> p4 = std::make_shared<A>(14);
myfunc(p4);
// 作为函数的返回值
auto p5 = myfunc1(p4); // 引用计数会变成3,这是因为有p5来接这个临时的智能指针。
cout <<" p4 count: "<<p4.use_count() << endl;
cout <<" p5 count: "<<p5.use_count() << endl;
myfunc(p4); // 没有变量来接这个临时的智能指针,则临时智能指针生命周期到了,引用计数从3恢复到2
p4.reset();
cout <<" p5 count: "<<p5.use_count() << endl;
p5.reset();
cout <<" p5 count: "<<p5.use_count() << endl;
std::cout<<"-----------"<<endl;
// 删除器
std::shared_ptr<A> p6(new A[5], deleter);
auto lambda1 = [](A *x){std::cout << "Custom Deleter\n";delete[] x;};//使用lambad表达式
shared_ptr<A> p7(new A[5], lambda1);
return 0;
}
版权声明:本文为sheng199463原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。