在C++11智能指針的使用過程中,一個很大的陷阱就是陷入了循環引用問題,這個問題類似於大型項目中兩個頭文件互相包含的問題,而在C++11中如果因爲使用智能指針而引發了循環引用問題,那麼其結果會導致智能指針無法釋放,導致動態內存泄漏。
1循環引用
下面是一個典型的循環引用示例:
class B;
class A {
public:
std::shared_ptr<B> pointer_B;
~A() {
std::cout << "A已經被刪除" << std::endl;
}
};
class B {
public:
std::shared_ptr<A> pointer_A;
~B() {
std::cout << "B已經被刪除" << std::endl;
}
};
int main()
{
{
std::shared_ptr<A> pointer_A(new A);
std::shared_ptr<B> pointer_B(new B);
pointer_A->pointer_B = pointer_B;
pointer_B->pointer_A = pointer_A;
}
getchar();
return 0;
}
上述兩個代碼中兩個智能指針pointer_A和pointer_B都不會被刪除,造成了內存泄漏。上述代碼存在循環引用問題,pointer_A和pointer_B引用計數爲2,在離開作用域之後,pointer_A和pointer_B的引用計數減爲1,但是並不會減爲0,導致了兩個智能指針都不會調用析構函數,造成了內存泄漏。
2 使用weak_ptr修復循環引用
在C++11中,要解決這種循環引用問題的一種方式是引入弱引用指針weak_ptr,weak_ptr主要用於監視shared_ptr,構造其引用計數不會加1,析構引用計數也不會減1,主要用於監測shared_ptr中所管理的指針資源是否存在。
使用weak_ptr修復循環引用問題如下:
class B;
class A {
public:
std::shared_ptr<B> pointer_B;
~A() {
std::cout << "A已經被刪除" << std::endl;
}
};
class B {
public:
std::weak_ptr<A> pointer_A;// 將shared_ptr修改爲weak_ptr
~B() {
std::cout << "B已經被刪除" << std::endl;
}
};
int main()
{
{
std::shared_ptr<A> pointer_A(new A);
std::shared_ptr<B> pointer_B(new B);
pointer_A->pointer_B = pointer_B;
pointer_B->pointer_A = pointer_A;
}
getchar();
return 0;
}
大家有興趣也可以訪問我的個站:www.stubbornhuang.com