c++ - Template based Subject Observer pattern - Should I use static_cast or dynamic_cast -
i referring article implementing subject/observer pattern templates
i did modification , became code follow.
template <class t, class a> class observer { public: observer() {} virtual ~observer() {} virtual void update(t& subject, arg) = 0; }; template <class t, class a> class subject { public: subject() {} virtual ~subject() {} // take note that, didn't make following functions virtual, // not expect them overridden. void attach(observer<t, a> &observer) { // ensure no duplication. std::vector<observer<t, a> *>::const_iterator iterator = std::find(observers.begin(), observers.end(), &observer); if (iterator == observers.end()) { observers.push_back(&observer); } } void dettach(observer<t, a> &observer) { std::vector<observer<t, a> *>::const_iterator iterator = std::find(observers.begin(), observers.end(), &observer); if (iterator != observers.end()) { observers.erase(iterator); } } void dettachall() { observers.clear(); } void notify(a arg) { std::vector<observer<t, a> *>::const_iterator it; (it = observers.begin(); != observers.end(); it++) { (*it)->update(*(static_cast<t *>(this)), arg); } } private: std::vector<observer<t, a> *> observers; }; later, realize (*it)->update(*(static_cast<t *>(this)), arg); having limitation. example,
// cause compilation error in static_cast, cannot cast cat1 animal. class cat1 : public animal, public subject<animal, int> { public: virtual void speak() { notify(888); } }; class zoo1 : public observer<animal, int> { public: zoo1() { c.attach(*this); c.speak(); } virtual void update(animal& subject, int arg) { cout << "zoo1 received notification " << arg << endl; } cat1 c; }; i can solve problem changing static_cast dynamic_cast. however, not sure whether fall other traps? guess on author original intention in having static_cast, ensure type safety checking during compile time.
your problem come fact animal should subject not cat,
class animal : public subject<animal,int> { ... }; class cat1 : public animal { public: virtual void speak() { notify(888); } }; class zoo1 : public observer<animal, int> { public: zoo1() { c.attach(*this); c.speak(); } virtual void update(animal& subject, int arg) { cout << "zoo1 received notification " << arg << endl; } cat1 c; }; by doing every subject static-cast "able" animal. not case cat1
Comments
Post a Comment