這時就有難題了,要怎麼知道其他持有者都放棄了,這時替死鬼就派上用場了,特殊的持有者仍持有該物件,其他持有者則改持有替身,等所有持有者放棄替身後,再由替身去要求特殊的持有者放棄該物件。
以下範例做到類似 Singleton 模式 的功能,差別只在物件無持有者時仍會被解構
#include <iostream>
#include <SMART_PTR.HPP>
#include <UTF8STRING.HPP>
#include <CXXLAVLTREE.HPP>
using namespace std;
using namespace CxxlMan2;
// Base
class A:virtual public cxxlObject
{
protected:
// 物件容器,新建構的物件保存一份
static cxxlAVL_Tree<A, UTF8_String, true> A_Tree;
};
cxxlAVL_Tree<A, UTF8_String, true> A::A_Tree;
class A1:public A
{
// Constructor
A1()
{
// 替身同時產生
pSbstituteu = new Sbstituteu_t(this);
cout << "A1 Constructor" << endl;
}
public:
// Destructor
virtual ~A1()
{
cout << "A1 Destructor" << endl;
}
void f()
{
cout << "A1::f()" << endl;
}
// 替死鬼
class Sbstituteu_t :public cxxlObject
{
Smart_Ptr<A1> A1_Ptr; // 主角,為它做替身
public:
Sbstituteu_t(A1 *a)
:A1_Ptr(a)
{
}
virtual ~Sbstituteu_t()
{
// 替身結束,也要刪除主角
A::A_Tree.Delete("A1");
}
A1 *operator->() const
{
return A1_Ptr;
}
}*pSbstituteu; // 用來取得替身
static Smart_Ptr<Sbstituteu_t> Create()
{
// 先在容器中找看看
Smart_Ptr<A> A_Ptr = A_Tree.GetObj("A1");
if (A_Ptr.isNULL()) // 若物件還未建立
{
A_Ptr = new A1;
A::A_Tree.Add(A_Ptr, "A1");
}
// 不傳回物件,而傳回替身
return (Smart_Cast<A1>(A_Ptr))->pSbstituteu;
}
};
// 每種物件都應有其對應的替死鬼
class A2 :public A
{
// Constructor
A2()
{
pSbstituteu = new Sbstituteu_t(this);
cout << "A2 Constructor" << endl;
}
public:
// Destructor
virtual ~A2()
{
cout << "A2 Destructor" << endl;
}
void f()
{
cout << "A2::f()" << endl;
}
class Sbstituteu_t :public cxxlObject
{
Smart_Ptr<A2> A2_Ptr;
public:
Sbstituteu_t(A2 *a)
:A2_Ptr(a)
{
}
virtual ~Sbstituteu_t()
{
A::A_Tree.Delete("A2");
}
A2 *operator->() const
{
return A2_Ptr;
}
}*pSbstituteu;
static Smart_Ptr<Sbstituteu_t> Create()
{
Smart_Ptr<A> A_Ptr = A_Tree.GetObj("A2");
if (A_Ptr.isNULL())
{
A_Ptr = new A2;
A::A_Tree.Add(A_Ptr, "A2");
}
return (Smart_Cast<A2>(A_Ptr))->pSbstituteu;
}
};
int main()
{
{
Smart_Ptr<A1::Sbstituteu_t> v1_Ptr = A1::Create();
(*v1_Ptr)->f();
Smart_Ptr<A1::Sbstituteu_t> v2_Ptr = A1::Create();
(*v1_Ptr)->f();
}
cin.get();
return 0;
}
執行結果:
可以看出 A1 只被建立一次,兩次 A1::Create() 所取得的都是同一份物件,無持有者時也能順利被解構
沒有留言:
張貼留言