C++ (Qt)#include <QCoreApplication>#include <QList>#include <QSharedPointer>#include <QDebug> template <class Manager, typename Element>class ElementManager : public QObject{public: explicit ElementManager(); virtual ~ElementManager(); void addElement(const Element &element); void removeElement(const Element &element); static Manager *instance(); private: QList<Element> m_elements; static Manager *m_instance;}; template <class Manager, typename Element>Manager *ElementManager<Manager, Element>::m_instance = nullptr; template <class Manager, typename Element>ElementManager<Manager, Element>::ElementManager(){ m_instance = static_cast <Manager*> (this);} template <class Manager, typename Element>ElementManager<Manager, Element>::~ElementManager(){ m_instance = nullptr;} template <class Manager, typename Element>void ElementManager<Manager, Element>::addElement(const Element &element){ m_elements.append(element);} template <class Manager, typename Element>void ElementManager<Manager, Element>::removeElement(const Element &element){ m_elements.removeOne(element);} template <class Manager, typename Element>Manager *ElementManager<Manager, Element>::instance(){ return m_instance;} class Foo : public QObject{ Q_OBJECTpublic: typedef QSharedPointer<Foo> Ptr; explicit Foo() = default;}; class FooManager: public ElementManager<FooManager, Foo::Ptr>{ Q_OBJECTpublic: explicit FooManager() = default; void do_something() { qDebug() << "FooManager: do something"; emit fooSomething(); } signals: void fooSomething();}; class Bar : public QObject{ Q_OBJECTpublic: typedef QSharedPointer<Bar> Ptr; explicit Bar() = default;}; class BarManager: public ElementManager<BarManager, Bar::Ptr>{ Q_OBJECTpublic: explicit BarManager() = default; void do_something() { qDebug() << "BarManager: do something"; emit barSomething(); } signals: void barSomething();}; int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); { new FooManager; auto p = FooManager::instance(); p->do_something(); } { new BarManager; auto p = BarManager::instance(); p->do_something(); } return a.exec();} #include "main.moc"
C++ (Qt)void removeElement(const Id &id);
C++ (Qt)p->do_something();
C++ (Qt)#include <QCoreApplication>#include <QList>#include <QSharedPointer>#include <QDebug> #include <algorithm> class IManager : public QObject{ Q_OBJECTsignals: void elementAdded(const QString &elementId); void elementRemoved(const QString &elementId); protected: void emitElementAdded(const QString &elementId) { emit elementAdded(elementId); } void emitElementRemoved(const QString &elementId) { emit elementRemoved(elementId); }}; class IElement : public QObject{public: explicit IElement(const QString &elementId) : m_elementId(elementId) { } QString id() const { return m_elementId; } private: QString m_elementId;}; template <class Manager, typename Element>class ElementManager : public IManager{public: explicit ElementManager(); virtual ~ElementManager(); Element element(const QString &elementId) const; void addElement(const Element &element); void removeElement(const QString &elementId); static Manager *instance(); private: QList<Element> m_elements; static Manager *m_instance;}; template <class Manager, typename Element>Manager *ElementManager<Manager, Element>::m_instance = nullptr; template <class Manager, typename Element>ElementManager<Manager, Element>::ElementManager(){ m_instance = static_cast <Manager*> (this);} template <class Manager, typename Element>ElementManager<Manager, Element>::~ElementManager(){ m_instance = nullptr;} template <class Manager, typename Element>Element ElementManager<Manager, Element>::element(const QString &elementId) const{ const auto end = m_elements.cend(); const auto it = std::find_if(m_elements.cbegin(), end, [elementId](Element element) { return element->id() == elementId; }); return (it == end) ? Element() : *it;} template <class Manager, typename Element>void ElementManager<Manager, Element>::addElement(const Element &element){ m_elements.append(element); emitElementAdded(element->id());} template <class Manager, typename Element>void ElementManager<Manager, Element>::removeElement(const QString &elementId){ auto e = element(elementId); if (e) { m_elements.removeOne(e); emitElementRemoved(e->id()); }} template <class Manager, typename Element>Manager *ElementManager<Manager, Element>::instance(){ return m_instance;} class Foo : public IElement{ Q_OBJECTpublic: typedef QSharedPointer<Foo> Ptr; explicit Foo(const QString &id) : IElement(id) { }}; class FooManager: public ElementManager<FooManager, Foo::Ptr>{ Q_OBJECTpublic: explicit FooManager() = default; void do_something() { qDebug() << "FooManager: do something"; emit fooSomething(); } signals: void fooSomething();}; class Bar : public IElement{ Q_OBJECTpublic: typedef QSharedPointer<Bar> Ptr; explicit Bar() : IElement(QLatin1String("bar.id")) { }}; class BarManager: public ElementManager<BarManager, Bar::Ptr>{ Q_OBJECTpublic: explicit BarManager() = default; void do_something() { qDebug() << "BarManager: do something"; emit barSomething(); } signals: void barSomething();}; int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); { new FooManager; auto p = FooManager::instance(); Foo::Ptr foo(new Foo(QLatin1String("foo1.id"))); p->addElement(foo); p->removeElement(QLatin1String("foo1.id")); p->do_something(); } { new BarManager; auto p = BarManager::instance(); p->do_something(); } return a.exec();} #include "main.moc"
C++ (Qt)class FooManager: public ElementManager<Foo::Ptr>{.. FooManager * instance( void ) { return static_cast<FooManager *> (m_instance); }
C++ (Qt)#include <QObject>#include <QVector>#include <QtDebug>#include <memory> class IManager{public: virtual void doSomething() = 0; virtual ~IManager(){ }}; class AbstractManager: public QObject, public IManager{ Q_OBJECT signals: void elementAdded(const QString &elementId); void elementRemoved(const QString &elementId);}; template<typename T>struct Element{ QString id; T value;}; template<class T>class ElementManager: public AbstractManager{ using ElementType = Element<T>; using Container = QVector<ElementType>;public: ElementManager(){ if (instance_){ qCritical() << "Overwritting ElementManager global instance"; } instance_ = this; } virtual ~ElementManager() override { instance_ = nullptr; } void addElement(const ElementType &element){ elements_ << element; emit elementAdded(element.id); } void removeElement(const QString &id){ typename Container::iterator it = find(id); elements_.erase(it); emit elementRemoved(id); } ElementType element(const QString &id) const{ return *find(id); } static IManager *instance(){ return instance_; } private: typename Container::iterator find(const QString &id){ for (typename Container::iterator it = elements_.begin(), end = elements_.end(); it != end; ++it){ if (it->id == id){ return it; } } return elements_.end(); } private: static IManager *instance_; Container elements_;}; template<typename T>IManager *ElementManager<T>::instance_ = nullptr; template<typename T>IManager *instance(){ return ElementManager<T>::instance();} class IntManager: public ElementManager<int>{public: IntManager(){ } virtual ~IntManager() override{ } virtual void doSomething() override{ qDebug() << "IntManager doing something"; }}; class StringManager: public ElementManager<QString>{public: StringManager(){ } virtual ~StringManager() override{ } virtual void doSomething() override{ qDebug() << "StringManager doing something"; }}; int main(){ using IntElement = Element<int>; using StringElement = Element<QString>; IntElement intElement; intElement.id = "int.id"; intElement.value = 7; IntManager intManager; QObject::connect(&intManager, &IntManager::elementAdded, [=](const QString &id){qDebug() << "Element with id" << id << "added to int manager";}); QObject::connect(&intManager, &IntManager::elementRemoved, [=](const QString &id){qDebug() << "Element with id" << id << "removed from int manager";}); intManager.addElement(intElement); StringElement stringElement; stringElement.id = "string.id"; stringElement.value = "Qt"; StringManager stringManager; stringManager.addElement(stringElement); std::array<IManager *, 2> intances{{ instance<int>(), instance<QString>() }}; for (IManager *instance: intances){ instance->doSomething(); } return 0;} #include "main.moc"
C++ (Qt)ElementType element(const QString &id) const{ return *find(id); }