用一個範例做個總結,也感謝 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; }
沒有留言:
張貼留言