- cxxlObject 已沒有在被使用時,垃圾處理核心會自動銷毀。
- cxxlObject 若還在被使用就不會被銷毀,所以持有者可以放心使用,因至少還有一個持有者還在使用。
#include <iostream>
#include <SMART_PTR.HPP>
using namespace std;
using namespace CxxlMan2;
class B;
class A:virtual public cxxlObject
{
Smart_Ptr<B> m_B_Ptr; // A 持有 B 物件
public:
// Constructor
A()
:m_B_Ptr(nullptr,this)
{}
// Destructor 實作在後面
~A();
friend class B;
};
class B :virtual public cxxlObject
{
Smart_Ptr<A> m_A_Ptr; // B 持有 A 物件
int i;
public:
// Constructor
B()
:m_A_Ptr(new A, this)
{
m_A_Ptr->m_B_Ptr = this;
}
void F1()
{
++i;
cout << "this is B::F1" << endl;
}
};
// Destructor
A::~A()
{
m_B_Ptr->F1(); // A 結束前叫用它所持有的 B 物件
}
int main()
{
{
// rootObject 持有 B 物件
Smart_Ptr<B> B_Ptr(new B);
}
// 等待所有的物件都結束
Wait_cxxlObjectDeathQueue_Emptied();
return 0;
}
當 main() 的 B_Ptr 結束後,A B 兩物件只剩互相持有,不再有實質的使用持有者,這時垃圾處理核心會結束掉這兩個物件,當 A 的解構函數去呼叫 B::F1() 有可能 B 物件已經不存在了(若 B 比較早被結束掉)。
因此在解構函數叫用持有的物件是有風險的,除非你能確定不會和持有的物件形成循環參照,解決的辦法是把解構函數的東西搬出來,做一個結束前的處理函數,在物件結束前先叫用
因此在解構函數叫用持有的物件是有風險的,除非你能確定不會和持有的物件形成循環參照,解決的辦法是把解構函數的東西搬出來,做一個結束前的處理函數,在物件結束前先叫用
沒有留言:
張貼留言