lundi 11 janvier 2016

Using RTTI with objects dervied from an external library

I am working with an external library and need to create an observer pattern where observers are derived from an object that belongs to the library. I do not want to change the base class from the library and at the same time I have to use the list of references/pointers to this unchangeable base class. The code I wrote is roughly equivalent to this:

#include <iostream>
#include <vector>
#include <typeinfo>

// This class is from an external library which I don't want to chagne
class BaseFromLibrary {
  public:
    virtual ~BaseFromLibrary() {}
};

class BaseOfObserver {
  public:
    void notify(){ std::cout << "What-ho!\n"; };
};

class Observer : public BaseFromLibrary, public BaseOfObserver {};

class Subject {
  public:
    std::vector<Observer *> observers;
    void notifyObervers() {
        for (auto o : observers)
            (*o).notify();
    }
};

int main() {
    std::vector<BaseFromLibrary *> list{new BaseFromLibrary(), new Observer()};
    Subject s;

    for (auto e : list)
        if (dynamic_cast<Observer *>(e) != nullptr)
            s.observers.push_back(dynamic_cast<Observer *>(e));

    s.notifyObervers();
}

Then I use the BaseOfObserver to add "subject awareness" to my other derived types. This way I do not have to repeat an if-statement for each specific observer I want to implement.

It seems to work fine, but is that a design mistake? Is there a better way to construct the observer list without RTTI mechanism and without interfering with the library classes?

Aucun commentaire:

Enregistrer un commentaire