C語言?智能指針?shared_ptr?和?weak_ptr
weak_ptr引入可以解決shared_ptr交叉引用時(shí)無法釋放資源的問題。
示例代碼:
#include <iostream>
#include <memory>
using namespace std;
class B;
class A{
public:
? ? A(){cout << "A constructor ... "<< endl;}
? ? ~A(){cout << "A destructor ..." << endl;}
? ? std::shared_ptr<B> pb;
};
class B{
public:
? ? B(){cout << "B constructor ... "<< endl;}
? ? ~B(){cout << "B destructor ..." << endl;}
? ? std::shared_ptr<A> pa;
};
int main(int argc, char **argv) {
? ??
? ? std::shared_ptr<int> a = std::make_shared<int>(3);
? ? std::shared_ptr<char> b = std::make_shared<char>('a');
? ??
? ? std::cout << "shared_ptr object(int) size = " << sizeof(a) << std::endl;
? ? std::cout << "shared_ptr object(char) size = " << sizeof(b) << std::endl;
? ??
? ? std::weak_ptr<A> shadow_a;
? ? std::weak_ptr<B> shadow_b;
? ??
? ? {
? ? std::shared_ptr<A> ptr_a = std::make_shared<A>();
? ? std::shared_ptr<B> ptr_b = std::make_shared<B>();
? ??
? ? shadow_a = ptr_a;
? ? shadow_b = ptr_b;
? ??
? ? ptr_a->pb = ptr_b;
? ? ptr_b->pa = ptr_a;
? ??
? ? cout << "reference count of A = " << shadow_a.use_count() << endl;
? ? cout << "reference count of B = " << shadow_b.use_count() << endl;
? ? cout << endl;?
? ? }
? ??
? ? cout << "reference count of A = " << shadow_a.use_count() << endl;
? ? cout << "reference count of B = " << shadow_b.use_count() << endl;
? ??
? ? std::cout << "Hello, world!" << std::endl;
? ? return 0;
}運(yùn)行代碼得到以下輸出:
shared_ptr object(int) size = 16
shared_ptr object(char) size = 16
A constructor ...
B constructor ...
reference count of A = 2
reference count of B = 2reference count of A = 1
reference count of B = 1
Hello, world!
從結(jié)果可以看出,由于交叉引用導(dǎo)致申請的內(nèi)存A,B無法正常釋放。
為什么會這樣呢?這個應(yīng)該從析構(gòu)原理進(jìn)行考慮,shared_ptr引用計(jì)數(shù)需要為0才會進(jìn)行析構(gòu)!但是ptr_a離開作用域會導(dǎo)致A引用計(jì)數(shù)減少1,但是A的引用計(jì)數(shù)此時(shí)為1,那么 pb不會釋放;同理,ptr_b離開作用域會導(dǎo)致B引用計(jì)數(shù)減少1,但是B的引用計(jì)數(shù)為此時(shí)為1,那么pa不會釋放。如此導(dǎo)致了資源無法釋放掉。
由于weak_ptr并不會改變shared_ptr的引用計(jì)數(shù),所以修改類A,和類B中的shared_ptr對象為weak_ptr對象即可釋放資源。
修改后的代碼如下:
#include <iostream>
#include <memory>
using namespace std;
class B;
class A{
public:
? ? A(){cout << "A constructor ... "<< endl;}
? ? ~A(){cout << "A destructor ..." << endl;}
? ? //std::shared_ptr<B> pb;
? ? std::weak_ptr<B> pb;
};
class B{
public:
? ? B(){cout << "B constructor ... "<< endl;}
? ? ~B(){cout << "B destructor ..." << endl;}
? ? //std::shared_ptr<A> pa;
? ? std::weak_ptr<A> pa;
};
int main(int argc, char **argv) {
? ??
? ? std::shared_ptr<int> a = std::make_shared<int>(3);
? ? std::shared_ptr<char> b = std::make_shared<char>('a');
? ??
? ? std::cout << "shared_ptr object(int) size = " << sizeof(a) << std::endl;
? ? std::cout << "shared_ptr object(char) size = " << sizeof(b) << std::endl;
? ??
? ? std::weak_ptr<A> shadow_a;
? ? std::weak_ptr<B> shadow_b;
? ??
? ? {
? ? std::shared_ptr<A> ptr_a = std::make_shared<A>();
? ? std::shared_ptr<B> ptr_b = std::make_shared<B>();
? ??
? ? shadow_a = ptr_a;
? ? shadow_b = ptr_b;
? ??
? ? ptr_a->pb = ptr_b;
? ? ptr_b->pa = ptr_a;
? ??
? ? cout << "reference count of A = " << shadow_a.use_count() << endl;
? ? cout << "reference count of B = " << shadow_b.use_count() << endl;
? ? cout << endl;?
? ? }
? ??
? ? cout << "reference count of A = " << shadow_a.use_count() << endl;
? ? cout << "reference count of B = " << shadow_b.use_count() << endl;
? ??
? ? std::cout << "Hello, world!" << std::endl;
? ? return 0;
}
運(yùn)行結(jié)果如下,可以正常釋放資源。
shared_ptr object(int) size = 16
shared_ptr object(char) size = 16
A constructor ...
B constructor ...
reference count of A = 1
reference count of B = 1B destructor ...
A destructor ...
reference count of A = 0
reference count of B = 0
Hello, world!
到此這篇關(guān)于C語言 智能指針 shared_ptr 和 weak_ptr的文章就介紹到這了,更多相關(guān) shared_ptr 和 weak_ptr內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言模擬實(shí)現(xiàn)memmove的示例代碼
memmove函數(shù)用于拷貝字節(jié),如果目標(biāo)區(qū)域和源區(qū)域有重疊的話,memmove能夠保證源串在被覆蓋之前將重疊區(qū)域的字節(jié)拷貝到目標(biāo)區(qū)域中,但復(fù)制后源內(nèi)容會被更改。本文主要介紹了C語言模擬實(shí)現(xiàn)memmove的示例代碼,需要的可以參考一下2022-12-12
C++使用windwos?api實(shí)現(xiàn)獲取計(jì)算機(jī)基本信息
這篇文章主要為大家詳細(xì)介紹了C++如何使用windwos?api實(shí)現(xiàn)獲取windwos計(jì)算機(jī)的基本信息,包括計(jì)算機(jī)名稱、操作系統(tǒng)版本、處理器信息等,需要的可以參考一下2023-04-04
C++中for循環(huán)與while循環(huán)的區(qū)別總結(jié)
這篇文章主要給大家介紹了關(guān)于C++中for循環(huán)與while循環(huán)的區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
C++實(shí)現(xiàn)LeetCode(210.課程清單之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(210.課程清單之二),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08

