|
|||||||
Как поместить указатель на объект в QMap, и затем работать с этим объектом, извлекая указатель из QMap
Время создания: 25.01.2021 15:01
Автор: xintrea
Текстовые метки: qt, qt5, QMap, контейнер, указатель, объект, ссылка, поместить, извлечь
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Принципы написания кода
Запись: xintrea/mytetra_syncro/master/base/1611576089he7andd12f/text.html на raw.github.com
|
|||||||
|
|||||||
Бывает так, что в QMap надо разместить указатели на объекты, и по этим указателям работать с ними. Например, в области видимости класса имеются следующие указатели на объекты: protected: QAction *actionDirectPreferencesMain =nullptr; QAction *actionDirectPreferencesAppearance =nullptr; QAction *actionDirectPreferencesCrypt =nullptr; QAction *actionDirectPreferencesSyncro =nullptr; QAction *actionDirectPreferencesRecordTable=nullptr; QAction *actionDirectPreferencesAttach =nullptr; QAction *actionDirectPreferencesKeyboard =nullptr; QAction *actionDirectPreferencesHistory =nullptr; QAction *actionDirectPreferencesMisc =nullptr; Эти указатели нужно единообразно проинициализировать. Если делать инициализацию напрямую, то код будет выглядеть примерно так: actionDirectPreferencesMain= new QAction("Main", this); menu->addAction(actionDirectPreferencesMain] ); actionDirectPreferencesAppearance= new QAction("Appearance", this); menu->addAction(actionDirectPreferencesAppearance] ); и т.д. Это очень многословно, и нужно следить за правильными именами для каждого объекта. Гораздо лучше сделать инициализацию табличным способом. Т .е. вначале надо составить таблицу, потом пробежать по ее данным в цикле. Если использовать данные из цикла, тогда сами команды инициализации можно написать только один раз: QMap< QString, QAction **> map; map["Main"] = &actionDirectPreferencesMain; map["Appearance"]= &actionDirectPreferencesAppearance; map["Crypt"] = &actionDirectPreferencesCrypt; map["Syncro"] = &actionDirectPreferencesSyncro; map["Note Area"] = &actionDirectPreferencesRecordTable; map["Attaches"] = &actionDirectPreferencesAttach; map["Keyboard"] = &actionDirectPreferencesKeyboard; map["History"] = &actionDirectPreferencesHistory; map["Misc"] = &actionDirectPreferencesMisc; for(auto pageName : map.keys()) { *map[pageName] = new QAction(pageName, this); menu->addAction( *map[pageName] ); } Здесь следует обратить внимание на то, что внутри QMap будут храниться не просто указатели на объект, а указатель на указатель (**). Это сделано из-за того, что если хранить в QMap просто указатель на объект, то при изменении значения этого указателя, оригинальный указатель меняться не будет. Будет меняться только указатель, размещенный внутри QMap, а он никакого отношения к исходному указателю не имеет, за исключением того, что хранит тот же адрес объекта, что и исходный указатель, так как получил это значение в момент инициализации элемента QMap. Поэтому в QMap хранится тип указатель на указатель (**), а инициализация таких указателей будет происходить путем записывания в элемент QMap адреса указателя (&) указателя на объект. И поэтому, для обращения к объекту по указателю внутри цикла, значение QMap надо разыменовывать. Да, синтаксис получается немного запутанным, зато он позволяет работать с указателями на объекты, сохраненные в QMap. Можно объяснить этот код другими словами. Имеется несколько типов объектов, которые друг с другом взаимодействуют:
Чтобы управляться с помощью QMap с какими-то объектами, необходимо в QMap хранить указатели на эти объекты. Получается, что если с помощью QMap нужно управляться с QAction *, то в QMap надо хранить указатель на QAction *. А это значит, что тип у такого значения должен быть QAction **. Дальнейшее использование адресов и разыменовываний просто происходит из понимания того, какой тип значения хранится в QMap. |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|