LINUX.ORG.RU

[Qt]указатели в контейнерах

 


0

3

Доброго времени суток! Хочу узнать как грамтно сделать следующую вещь: Необходимо в ассоциативном массиве хранить указатель на QTcpSocket и указатель на некоторую структуру, что-то вроде:

QMap connections(QTcpSocket *, socketParams *).
И в идеале хотелось бы просто делать delete(connections), т.е. что б все автоматически красиво удалялось. Или лучше просто в деструкторе foreach-ем пробежаться по мапу и все вручную удалить?


лучше наверное умные указатели использовать

trashymichael ★★★
()

typedef QSharedPtr <QTcpSocket> QTcpSocketPtr; typedef QSharedPtr <socketParams> socketParamsPtr;

QMap <QTcpSocketPtr, socketParamsPtr> connections;

panter_dsd ★★★★
()

я бы структуры замутил


public class Connection
{
public:
   QTcpSocket *socket;
   socketParams *socket_params;
   public ~Connection()
   {
      //удаление переменных закрытие сокета
   }
}

public class Connections
{
public:
   vector<Connection*> all_conns;  //можно и QList
   ~Connection()
   {
      for(int i=0;i<all_cons.size();i++)
      {
          Connection* con1 = (Connection*)all_cons[i];
          delete con1;//вызовет деструктор
      }
   }
}



//гдето в коде
Connections conne = new Connections();
//добавление сокетов и т.д. и т.п.
delete conne;//все сделается само

pozitiffcat ★★★
()

>лучше просто в деструкторе foreach-ем пробежаться по мапу и все вручную удалить
+1

Кроме того рекомендую подписатся на удаление QTcpSocket (там есть соотв. слот), чтоб удалять из карты эти записи (для этого можно использовать sender()).

trex6 ★★★★★
()

Умные указатели, Люк.

yoghurt ★★★★★
()
Ответ на: комментарий от pozitiffcat

boost::ptr_set boost::ptr_map

они сами когда их деструктор вызывается бегают по коллекции и дергают delete для каждого указателя снимая эту задачу с кодера

anonymous
()
Ответ на: комментарий от anonymous

юзал я эту шляпу и понял, что лучше удалять все ручками, хоть, знаешь что делаешь, а эти бусты ведут себя как хотят. И вообще поэтому я сейчас пишу на яве =)

pozitiffcat ★★★
()
Ответ на: комментарий от pozitiffcat

это конечно шляпное решение если можно было хранить копии итемов в нодах а не указатели на них ТС может расскажет почему итменно указатели надо

anonymous
()
Ответ на: комментарий от pozitiffcat

С++ же траходром для очень гибких задач писать на нем простой быдлософт себе дороже времени уйму потратиш и силы тоже а отдача никакая какой нить задрот на дотнете тоже самое сделает быстрее и деньги получит но что в нем привлекает так это траходром кому не нравятся тупые языки

anonymous
()

Если использовать QSharedPointers, то для того что бы просто удалить элемент из QMap надо делать, что-то вроде:

QTcpSocket* socket = static_cast<QTcpSocket*>(sender());
socket->close();
QSharedPointer<QTcpSocket> * p = reinterpret_cast<QSharedPointer<QTcpSocket> *>(socket->parent());
connections.remove(*p);
Вручную тоже не совсем удобно - придется при удалении какого-либо элемента из контейнера дописывать везде delete для ключа и для значения.

Или я что-то не понимаю?

najar
() автор топика
Ответ на: комментарий от anonymous

потратиш
и силы тоже а отдача
деньги получит но что

...

anonymous
()
Ответ на: комментарий от najar

Зачем здесь QShartedPointer я так и не понял. Не проще ли просто удалить p из карты? И в каком слоте Вы предлагаетет это делать?

trex6 ★★★★★
()
Ответ на: комментарий от panter_dsd

ок.

typedef QSharedPointer<socketParameters> pSocketParameters;
typedef QSharedPointer<QTcpSocket> pSocket;
QMap<pSocket, pSocketParameters> m_connections;
Теперь, допустим, некоторый инстанс QTcpSocket испускает некоторый сигнал. И я хочу удалить эдемент из QMap, содержащий этот сокет, точнее сожержащий QSharedPointer.

Как это сделать правильно?

najar
() автор топика
Ответ на: комментарий от panter_dsd

Я понимаю, что так можно. Но такой оверхед для удаления... это нормально?)

najar
() автор топика

Инкапсулируй свой QMap в каком-нибудь CConnectionsPool, и не парь людям моск

class CConnectionsPool
{
public:
....
   // Gets ownership over _sock and _struct
   void registerConnection(QTcpSocket *_sock, SMyUglyStruct *_struct);

   // Returns registered struct or NULL if not found
   // Important: returned pointer will be valid as long as
   //            _sock is in the pool. (а может вообще лучше возвращать копию, зависит от твоей задачи)
   SMyUglyStruct * getMyUglyStruct(_sock) const;


   void unregisterConnection(QTcpSocket *_sock);
   ...

private:
   QMap<QTcpSOcket *, SMyUglyStruct *> m_pool;
};
anonymous
()
Ответ на: комментарий от Obey-Kun

А, блин, использует. Чё, неужели обратно от итераторов к foreach возвращаться там, где это читаемость повысит...

Obey-Kun ★★★★★
()
Ответ на: комментарий от Chaser_Andrey

> (как при работе с STL)?

при работе с STL - классические как раз итераторы

for(int i = 0; i < list->count(); i++)


тип лучше брать беззнаковый, count() выносить из цикла

list->at(i)


тут at() лишний, а если и использовать - то только с обработчиком

aho
()
Ответ на: комментарий от Chaser_Andrey

С итераторами зачастую удобней работать. Да и для некоторых контейнеров итерировать быстрее, чем дёргать at или operator[]

Obey-Kun ★★★★★
()
Ответ на: комментарий от aho

тип лучше брать беззнаковый, count() выносить из цикла

или лучше так:

for(quint16 i = list->count(); i; --i)

do0dlez ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.