首先要明白shared_ptr管理对象的语意,用shared_ptr管理的对象,那么默认这个对象只会被shared_ptr所管理。只有在shared_ptr之间相互赋值才会导致引用计数+1;下面的代码就会造成两次a的析构。
class A{
public:
~A(){
cout<<"~A"<<endl;
}
};
int main(){
A *ptr = new A();
shared_ptr<A> ptr_1(ptr);
cout<<ptr_1.use_count()<<endl;
shared_ptr<A> ptr_2 (ptr);
cout<<ptr_2.use_count()<<endl;
}
上面的代码会导致指针ptr指向的对象被析构两次,shared_ptr 的引用要增加的话,是在另外的shared_ptr 上面增加的,如果是在裸指针上面的转型成为shared_ptr的话,那么引用计数初始化为1。
还是那句,用shared_ptr管理的对象,那么默认这个对象生命周期只会被shared_ptr所管理,如果我们在fun函数里面如果返回一个A的对象,因为我们是用shared_ptr管理我们的类对象,所以返回的时候,也应该是返回一个shared_ptr,按照如下的方式返回对象的话:
class A{
public:
~A(){
cout<<"~A"<<endl;
}
shared_ptr<A> fun(){
shared_ptr<A> tmp_ptr (this);
return tmp_ptr;
}
void Print(){
cout<<"OK"<<endl;
}
};
int main(){
shared_ptr<A> ptr_1(new A());
shared_ptr<A> ptr_2 = ptr_1->fun();
ptr_2->Print();
}
[打印结果]对象被析构了两次:
OK
~A
~A
还用一种使用情况,就是,当另外的代码使用这个由this转换而来的shared_ptr的时候,其实这个对象已经被析构了:
class A{
public:
~A(){
cout<<"~A"<<endl;
}
shared_ptr<A> fun(){
shared_ptr<A> tmp_ptr (this);
return tmp_ptr;
}
void Print(){
cout<<"OK"<<endl;
}
};
int main(){
A *ptr = new A();
shared_ptr<A> ptr_2 ;
{
shared_ptr<A> ptr_1(ptr);
ptr_2 = ptr_1 ->fun();
}
ptr_2->Print();//其实A已经析构
}
打印结果:
~A
OK
~A
OK
~A
当我们加入了enable_shared_from_this以后,就可以能够让外部对象获取到这个对象的指针了
class A :public enable_shared_from_this<A>{
public:
~A(){
cout<<"~A"<<endl;
}
shared_ptr<A> fun(){
return shared_from_this();
}
void Print(){
cout<<"OK"<<endl;
}
};
int main(){
shared_ptr<A> ptr_1(new A());
shared_ptr<A> ptr_2 = ptr_1->fun();
ptr_2->Print();
}
那么,我们什么时候会需要用到这种返回对象的方式呢?
文章参考:
http://hahaya.github.io/use-enable-shared-from-this/
另外:
用shared_ptr需要注意的地方参考:http://www.cnblogs.com/lzjsky/archive/2011/09/09/2172469.html
一个是在构造函数里面不能够调用enable_from_this,一个是一个类的继承关系里面不能够有两个或者以上的enabl_from_this
同样的,下面的代码也有问题
class A :public enable_shared_from_this<A>{
public:
~A(){
cout<<"~A"<<endl;
}
shared_ptr<A> fun(){
return ptr_;
}
void Initial(){
ptr_ = shared_from_this() ;
}
void Print(){
cout<<"OK"<<endl;
}
shared_ptr<A> ptr_;
};
int main(){
{
shared_ptr<A> ptr_1(new A());
ptr_1->Initial();
shared_ptr<A> ptr_2 =
ptr_1 ->fun();
}
}
函数结束以后,并没有输出我们想要的~A,是因为这个时候A内部有一个shared_ptr 导致了引用计数永远不会为0 ,其实这也是一个循环引用的问题。
那么,为了能够不让这个引用计数永远不能够为0,就是解决循环引用的问题,引入了weak_ptr,它是对象的一个观察者。
那么,实际上,enablefromthis就是这么干的,enable fromthis 内部有一个weakptr,当继承自它的对象第一次调用sharedptr的构造函数后,这个weak ptr将被初始化,以后,每次调用sharedfromthis的时候,就会对这个weakptr做操作。