Russian Qt Forum
Май 17, 2024, 11:55 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QMap и типы ключей Key  (Прочитано 13442 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« : Январь 28, 2009, 12:56 »

Например такая ситуация, где в качестве ключа используется структура или класс, возвратит ли QMap нужный объект?

Ситуация №1 (в качестве ключа Qmap - класс):

Код:
//имеется класс ключей
class TMyKey
{
   int i;
   int j;
}
//имеется класс объекта
class TMyObj
{
...
}
...
//объявляем переменные ключей
TMyKey Key1;
TMyKey Key2;
....

QMap< TMyKey , *TMyObj> map
....
//инициализируем ключи данными
Key1.i = 1;
Key1.j = 1;

Key2.i = 2;
Key2.j = 2;

//создаем объекты и заносим в мапу ключи и указатели на объекты
TMyObj *myObj1 = new TMyObj ;
 map.insert(Key1, myObj1 );

TMyObj *myObj2 = new TMyObj ;
map.insert(Key2, myObj2 );


потом где-то в программе объявляем:
Код:
TMyKey  Key3;
Key3.i = 2;
Key3.j = 2;
и делаем:
Код:
TMyObj *myObj3 = map.value( Key3 );
Вопрос: вернет ли мапа указатель на объект myObj2 Непонимающий

=====================================================

Ситуация №2 (в качестве ключа QMap - указатель на класс):!!!

Код:
//имеется класс ключей
class TMyKey
{
   int i;
   int j;
}
//имеется класс объекта
class TMyObj
{
...
}
...
//объявляем переменные ключей НО по другому!!!
TMyKey *Key1 = new TMykey;
TMyKey *Key2 = new TMyKey;
....

QMap< *TMyKey , *TMyObj> map
....
//инициализируем ключи данными
Key1->i = 1;
Key1->j = 1;

Key2->i = 2;
Key2->j = 2;

//создаем объекты и заносим в мапу указатели на ключи и указатели на объекты
TMyObj *myObj1 = new TMyObj ;
 map.insert(Key1, myObj1 );

TMyObj *myObj2 = new TMyObj ;
map.insert(Key2, myObj2 );


потом где-то в программе объявляем:
Код:
TMyKey  *Key3 = new TMyKey;
Key3->i = 2;
Key3->j = 2;
и делаем:
Код:
TMyObj *myObj3 = map.value( Key3 );
Вопрос: вернет ли мапа указатель на объект myObj2 Непонимающий

Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Январь 28, 2009, 13:00 »

PS: для меня это вопрос жизни и смерти! Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #2 : Январь 28, 2009, 13:03 »

А проверить самому? Подмигивающий

Первый пример даже не скомпилятся. Дело в том, что ваши ключ должны иметь operator<():

Цитировать
QMap's key type must provide operator<(). QMap uses it to keep its items sorted, and assumes that two keys x and y are equal if neither x < y nor y < x is true.

Если в ключе должны быть 2 поля, то не проще бы было использовать QPair вместо своей структуры данных? Если это только пример, то реализуйте operator<().

Во втором примере нужно будет постоянно следить за освобождением памяти, занимаемой ключем.
« Последнее редактирование: Январь 28, 2009, 13:44 от pastor » Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Rcus
Гость
« Ответ #3 : Январь 28, 2009, 13:19 »

Среда это такая маленькая пятница? Веселый
Курите учебники, главу про указатели /*worships Code Complete*/
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Январь 28, 2009, 13:24 »

эээ... просто мне ключа типа INT мало.... т.е в моем случае ключем должна являться некая "ссылка"
т.е ссылка - некая структкра -  должна состоять из нескольких полей (мне нужно из 7 полей типа Int) - где каждое поле что-то кодирует...

т.е суть в следующем:
1. например из какой-то подсистемы А моего приложения приходит сигнал : dataChanged(Link, Data) предназначающийся для подсистемы Б
2. подсистема Б отловила этот сигнал и начинает "раскодирование" ссылки, т.е сопоставление ее с ссылкой, что записана у нее в QMap - для того, чтобы выделить тот объект в подсистеме Б , для которого предназначены данные Data.

т.е.  если бы мне хватило типа ссылки Link = int - то я б даже и не спрашивал и не парился бы... Грустный
я бы сделал бы так:
Код:
TMyClass *myObj = map.value( Link ); 

и потом бы :
Код:
myObj->setData(Data); 


 
Записан

ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #5 : Январь 28, 2009, 13:29 »

я сначала хотел состряпать алгоритм поиска объектов перебором по совпадению "ссылки" , которая зранится в текущем выбранном объекте с "ссылкой" - которая пришла с сигналом...
но увидел что в QT есть тип QMap и уж было обрадовался Грустный
Записан

ArchLinux x86_64 / Win10 64 bit
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #6 : Январь 28, 2009, 13:30 »

Откройте в ассистанте описание QMap. Там есть пример -  class Employee. Это ваш случай.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #7 : Январь 28, 2009, 13:48 »

спс Улыбающийся

т.е так:
Код:
class TLink
{
public:
   int Id1;
   int Id2;
   int Id3;
   ..........
   int InN;
}

inline bool operator<(const TLink&L1, const TLink&L2)
{
    if (L1.Id1 != L2.Id1) return L1.Id1 < L2.Id1);
    if (L1.Id2 != L2.Id2) return L1.Id2 < L2.Id2);
    if (L1.Id3 != L2.Id#) return L1.Id3 < L2.Id3);
............................................................................
    if (L1.IdN != L2.IdN) return L1.IdN < L2.IdN);
}

1. после этого уже мой класс TLink можно применять в качастве ключа key для QMap ?
2. И больше не нужно делать  operator>, operator= и т.д. и т.п ?

Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #8 : Январь 28, 2009, 14:25 »

Скорее всего вот так:

Код
C++ (Qt)
inline bool operator<(const TLink&L1, const TLink&L2)
{
   if (L1.Id1 != L2.Id1) return L1.Id1 < L2.Id1);
   if (L1.Id2 != L2.Id2) return L1.Id2 < L2.Id2);
   if (L1.Id3 != L2.Id3) return L1.Id3 < L2.Id3);
............................................................................
   return L1.IdN < L2.IdN);
}
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #9 : Январь 28, 2009, 14:33 »

Спасибо!

Зы: а откудава Вы, pastor и Ko,  все это знаете? У вас прям на все есть ответы! Ужос! Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #10 : Январь 28, 2009, 15:00 »

Это боты-компилляторы с искусственным интеллектом, находу парсят код и выдают ответы. Есть правда проблемы с русским языком, "ститические сборки" всякие, но мы работаем над этим вопросом.
Записан
Rcus
Гость
« Ответ #11 : Январь 28, 2009, 15:05 »

Не понял магический смысл проверки неравенства чисел типа int перед проверкой <...
В примере Qt была проверка объектов QString (== это всего-лишь проверка совпадения размера и memcmp, а < это ucstrcmp)
Записан
Dendy
Гость
« Ответ #12 : Январь 28, 2009, 15:10 »

Не понял магический смысл проверки неравенства чисел типа int перед проверкой <...

Если можно проверить по первому числу - остальные неважны. Если первые числа равны, проверяются вторые. И так до последнего, наименее значимого.
Записан
Rcus
Гость
« Ответ #13 : Январь 28, 2009, 15:13 »

Код
C++ (Qt)
if (L1.Id1 < L2.Id1) return true;
?
ADD: хотя нет, не пойдет
« Последнее редактирование: Январь 28, 2009, 15:17 от Rcus » Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #14 : Январь 28, 2009, 15:14 »

Есть правда проблемы с русским языком, "ститические сборки" всякие, но мы работаем над этим вопросом.

Улыбающийся
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.087 секунд. Запросов: 20.