用一個範例做個總結,也感謝 coco 提供的 assert,在 C++ 沒有提供 must 繼承實作之下,還能做到類似的效果,讓程式簡潔不少。但問題由原本的強制繼承實作,變成須強制 assert 實作,更不好達成,由此看出 must 繼承實作的須要性
範例主要展示 prototype pattern 及 visitor pattern 的架構,不過 visitor pattern 做了改良,可以
採用 ClassID 做配對,可以在執行時期做較機動的處理,但為了減少篇幅和難度,還是寫死未做較機動的
處理
Class C 是為了表現未強制實作的後果,有幾處做了 remark,把 remark 的地方恢復,就可正常執行
#include <map> #include <memory> #include <string> #include <assert.h> /* assert */ #include <typeinfo> /* assert */ #include <iostream>
using namespace std;
// 插件的識別碼 #define Base_ClassID u8"14432A2FAECE4DA7A33CDA7472FB61DE" #define A_ClassID u8"9EED77B5BD97404B85A390E2806FE435" #define B_ClassID u8"11B5DCB493744F9B9A7C14343CF609A6" #define C_ClassID u8"20DB108E78284B8390D258A4626523AC"
class Visitor; class Base;
class Prototype
{
virtual Prototype *Clone() const = 0;
public:
};
class Acceptor
{
virtual string GetClassID() const = 0;
public:
virtual void Accept(Visitor *v) = 0;
friend class Visitor; };
class Visitor
{
protected:
string GetClassID(Acceptor *pAcceptor) const
{
return pAcceptor->GetClassID();
}
virtual void Visit(Acceptor *pAcceptor) = 0; public: friend class Base; };
class Base:public Prototype, public Acceptor
{
virtual string GetClassID() const override
{
// 不准許 Base 被繼承卻沒有覆寫 GetClassID()
assert(strcmp(typeid(Base).name(), typeid(*this).name()) == 0);
return Base_ClassID;
}
virtual void Accept(Visitor *v) override final
{
v->Visit(this);
}
public:
virtual Base *Clone() const override
{
// 不准許 Base 沒有被繼承還執行 Clone()
assert(strcmp(typeid(Base).name(), typeid(*this).name()) != 0);
return new Base(*this);
}
};
/***/
class CustomVisitor
{
public:
virtual void Visit(Acceptor *pAcceptor) const = 0;
};
class VisitorManager :public Visitor
{
map<string, shared_ptr<CustomVisitor> > m_CustomVisitorMap;
virtual void Visit(Acceptor *pAcceptor) override
{
string ID = GetClassID(pAcceptor);
shared_ptr<CustomVisitor> CustomVisitor_Ptr = m_CustomVisitorMap[ID];
if (CustomVisitor_Ptr) CustomVisitor_Ptr->Visit(pAcceptor); else cout << "物件找不到相應的 CustomVisitor" << endl; } public: VisitorManager(); };
class ObjPool
{
map<string, shared_ptr<Base> > m_BaseMap;
public:
ObjPool();
Base *Get(string ClassID)
{
shared_ptr<Base> Src = m_BaseMap[ClassID];
if (Src)
return Src->Clone();
else
return nullptr;
}
};
/***/
class BaseVisitor :public CustomVisitor
{
virtual void Visit(Acceptor *pAcceptor) const override
{
Base *pBase = static_cast<Base*>(pAcceptor);
cout << "Base 被 Clone,請檢查..." << endl;
}
public:
};
class A :public Base
{
string m_Name{ "class A" };
virtual string GetClassID() const override
{
// 不准許 A 被繼承卻沒有覆寫 GetClassID()
assert(strcmp(typeid(A).name(), typeid(*this).name()) == 0);
return A_ClassID;
}
virtual A *Clone() const override
{
// 不准許 A 被繼承卻沒有覆寫 Clone()
assert(strcmp(typeid(A).name(), typeid(*this).name()) == 0);
return new A(*this);
}
public:
void SayHI()
{
cout << "HI! My name is " << m_Name << endl;
}
};
class B :public Base
{
string m_Name{ "class B" };
virtual string GetClassID() const override
{
// 不准許 B 被繼承卻沒有覆寫 GetClassID()
assert(strcmp(typeid(B).name(), typeid(*this).name()) == 0);
return B_ClassID;
}
virtual B *Clone() const override
{
// 不准許 B 被繼承卻沒有覆寫 Clone()
// assert(strcmp(typeid(B).name(), typeid(*this).name()) == 0);
return new B(*this);
}
public:
void SayHello()
{
cout << "Hello! My name is " << m_Name << endl;
}
};
class C :public B
{
int Age{ 100 };
virtual string GetClassID() const override
{
// 不准許 C 被繼承卻沒有覆寫 GetClassID()
assert(strcmp(typeid(C).name(), typeid(*this).name()) == 0);
return C_ClassID;
}
/*
virtual C *Clone() const override
{
// 不准許 C 被繼承卻沒有覆寫 Clone()
assert(strcmp(typeid(C).name(), typeid(*this).name()) == 0);
return new C(*this);
}
*/
public:
void HowOld()
{
cout << "I am " << Age << " years old" << endl;
}
};
class AVisitor :public CustomVisitor
{
virtual void Visit(Acceptor *pAcceptor) const override
{
// assert(strcmp(typeid(A).name(), typeid(*pAcceptor).name()) == 0);
A *pA = static_cast<A*>(pAcceptor); pA->SayHI(); cout << "A 複製成功..." << endl; } public: };
class BVisitor :public CustomVisitor
{
virtual void Visit(Acceptor *pAcceptor) const override
{
// assert(strcmp(typeid(B).name(), typeid(*pAcceptor).name()) == 0);
B *pB = static_cast<B*>(pAcceptor); pB->SayHello(); cout << "B 複製成功..." << endl; } public: };
class CVisitor :public CustomVisitor
{
virtual void Visit(Acceptor *pAcceptor) const override
{
// assert(strcmp(typeid(C).name(), typeid(*pAcceptor).name()) == 0);
C *pC = static_cast<C*>(pAcceptor); pC->SayHello(); pC->HowOld(); cout << "C 複製成功..." << endl; } public: };
ObjPool::ObjPool()
{
// 註冊所有 Base 的 Derived
m_BaseMap[string(Base_ClassID)] = shared_ptr<Base >(new Base);
m_BaseMap[string(A_ClassID)] = shared_ptr<Base >(new A);
m_BaseMap[string(B_ClassID)] = shared_ptr<Base >(new B);
m_BaseMap[string(C_ClassID)] = shared_ptr<Base >(new C);
}
VisitorManager::VisitorManager()
{
// 註冊所有 CustomVisitor 的 Derived
m_CustomVisitorMap[string(Base_ClassID)] = shared_ptr<CustomVisitor >(new BaseVisitor);
m_CustomVisitorMap[string(A_ClassID)] = shared_ptr<CustomVisitor >(new AVisitor);
m_CustomVisitorMap[string(B_ClassID)] = shared_ptr<CustomVisitor >(new BVisitor);
m_CustomVisitorMap[string(C_ClassID)] = shared_ptr<CustomVisitor >(new CVisitor);
}
int main()
{
ObjPool MyObjPool;
VisitorManager MyVisitorManager;
shared_ptr<Base> Obj_Ptr(MyObjPool.Get(string(A_ClassID))); shared_ptr<Acceptor> Acceptor_Ptr = static_pointer_cast<Acceptor>(Obj_Ptr); Acceptor_Ptr->Accept(&MyVisitorManager);
cout << endl; Obj_Ptr = shared_ptr<Base>( MyObjPool.Get(string( C_ClassID )) ); Acceptor_Ptr = static_pointer_cast<Acceptor>(Obj_Ptr); Acceptor_Ptr->Accept(&MyVisitorManager);
return 0; }
沒有留言:
張貼留言