template <typename T>class List : public QList<T>{public: T add(T item){ append(item); connect(item, SIGNAL(destroyed(QObject*), this, SLOT(_destroyed(QObject*))); }private slot: void _destroyed(QObject*object){ removeOne(object); // как-то так.... }};
List<MyPoint*> list;MyPoint * p1 = new MyPoint();MyPoint * p2 = new MyPoint();MyPoint * p3 = new MyPoint();list.add(p1);list.add(p2);list.add(p3);qDebug() << "size: " << list.size(); // size: 3delete p2;qDebug() << "size: " << list.size(); // ДОЛЖНО БЫТЬ size: 2, сейчас возвращает size: 3
template <class T>class List : public QList<T *>{public: void add(T * item) { append(item); connect(item, SIGNAL(destroyed(QObject*), this, SLOT(_destroyed(QObject*))); }private slot: void _destroyed(QObject*object) { removeOne((T *) object); }};
QList<MyObject *> list;MyObject * obj1 = new MyObject();list.append(obj1); // list.size = 1delete obj1; // list.size = 1// что останется в list ? указатель на мусор...
class DestroyProcessor : public QObject{ Q_OBJECTpublic: void SetList(QList<QObject*>* list) { m_list = list ; }public slots: void ProcessDestroyed ( QObject * obj = 0 ) { if (m_list) { m_list->removeOne(object); } }protected: QList<QObject*>* m_list ;}template <class T>class List : public QList<T *>{public: List() { m_destroyProcessor = new DestroyProcessor() ; m_destroyProcessor->setList(this) ; } void add(T * item) { append(item); connect(item, SIGNAL(destroyed(QObject*), m_destroyProcessor, SLOT(ProcessDestroyed(QObject*))); }private : DestroyProcessor* m_destroyProcessor ;};
class MyObject;// абстрактный класс слушателя события удаления объектаclass DestroyListener{public: DestroyListener() {} virtual void destroy(MyObject*object)=0; };// статический класс принимает и рассылает уведомленияclass ObjectsManager{public: static inline void registry(MyObject*object, DestroyListener*listener) { _listeners.insertMulti(object, listener); } static inline void destroy(MyObject * object) { QList<DestroyListener*> listeners = _listeners.values(object); _listeners.remove(object); // оповещаем о удалении всех зарегистрированных слушателей foreach(DestroyListener*listener, listeners){ listener->destroy(object); } }private: static QMultiMap<MyObject*, DestroyListener*> _listeners;};QMultiMap<MyObject*, DestroyListener*> ObjectsManager::_listeners;// базовый классclass MyObject{public: MyObject() {} virtual ~MyObject() { // сообщаем о удалении ObjectsManager::destroy(this); }};template <typename T>class List : public QList<T>, DestroyListener{public: T add(T item){ QList<T>::append(item); // подписываемся на получения событий удаления ObjectsManager::registry(item, this); return item; } void destroy(MyObject*object) { // реализуем реакцию на уничтожение объекта, т.е. выносим его из списка T item = static_cast<T>(object); removeOne(item); }};// тестовый классclass TestObject : public MyObject{public: TestObject(int i) : MyObject(), _i(i) { } inline int getI(){ return _i; }private: int _i;};
QTime timer; timer.start(); List<TestObject*> list; int n = 100000; for(int i=0; i < n; i++){ TestObject * t = new TestObject(1); list.add(t); } qDebug() << timer.elapsed() << list.size(); TestObject * t = list.at(n/2); delete t; qDebug() << timer.elapsed() << list.size();