- 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 比較早被結束掉)。
因此在解構函數叫用持有的物件是有風險的,除非你能確定不會和持有的物件形成循環參照,解決的辦法是把解構函數的東西搬出來,做一個結束前的處理函數,在物件結束前先叫用
因此在解構函數叫用持有的物件是有風險的,除非你能確定不會和持有的物件形成循環參照,解決的辦法是把解構函數的東西搬出來,做一個結束前的處理函數,在物件結束前先叫用
沒有留言:
張貼留言