上一篇介紹了四種智能指針,四種智能指針的特點及使用方法
看段代碼:
class B;
class A
{
public:
A(){ cout << "A()" << endl; }
A(int i):a(i){ cout << "A(int)" << endl;}
~A(){ cout << "~A()" << endl;}
shared_ptr<B> _bptr;
int a;
};
class B
{
public:
B(){ cout << "A()" << endl; }
B(int i):b(i){ cout << "A(int)" << endl;}
~B(){cout << "~B()" << endl;}
shared_ptr<A> _aptr;
int b;
};
int main()
{
shared_ptr<A> aptr(new A(10));
shared_ptr<B> bptr(new B(10));
cout << aptr.use_count() << endl;
aptr -> _bptr = bptr;
bptr -> _aptr = aptr;
cout << aptr.use_count() << endl;
return 0;
}
導致程序結束也沒有調用類的析構函數,在堆上申請的資源沒有得到正確的釋放,shared_ptr不恰當的使用帶來的循環用問題
這樣在函數返回的時候,shared_ptr<a> aptr 這個智能指針調用析構函數,對堆上的資源A的引用計數減一,此時引用計數爲1,不爲0,不調用delete函數,資源B同資源A一樣,引用計數爲1,這樣導致堆上的資源得不到正確的釋放,內存泄露。
改進方法:因爲在類的內部使用了帶有引用計數的強智能指針,導致對象的一直被循環引用,A對象內部的強智能指針指向B對象,B對象內部的強智能指針指向A對象。 把智能指針變成不使用引用計數的weak_ptr智能指針問題就得到解決了.(weak_ptr不增加引用計數,能看到引用計數)
class B;
class A
{
public:
A(){ cout << "A()" << endl; }
A(int i):a(i){ cout << "A(int)" << endl;}
~A(){ cout << "~A()" << endl;}
weak_ptr<B> _bptr; //修改成弱智能指針
int a;
};
class B
{
public:
B(){ cout << "A()" << endl; }
B(int i):b(i){ cout << "A(int)" << endl;}
~B(){cout << "~B()" << endl;}
weak_ptr<A> _aptr; //修改成弱智能指針
int b;
};
int main()
{
shared_ptr<A> aptr(new A(10));
shared_ptr<B> bptr(new B(10));
cout << aptr.use_count() << endl;
aptr -> _bptr = bptr;
bptr -> _aptr = aptr;
cout << aptr.use_count() << endl;
return 0;
}
圖畫的有點醜,紅色和淡藍色的線是可以看到引用計數,但是不會增加引用計數
堅持✊