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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QList и indexOf  (Прочитано 12902 раз)
surendil
Гость
« : Август 19, 2011, 00:04 »

Здравствуйте Улыбающийся Ломаю голову над проблемой уже шестой час, но никак не могу понять, почему не работает. Помогите пожалуйста...

Я хочу сделать QList< USBID* > и искать их по indexOf(). Как было написано в документации на QList, я реализовал в USBID оператор сравнения, получилось так:
Код
C++ (Qt)
bool USBID::operator ==(USBID &cmpId) const
В ходе отладки выяснилось, что до выполнения моего operator == дело не доходит.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Август 19, 2011, 00:25 »

эта функция сравнения подойдет для QList<USBID>, а для QList<USBID *> нужно реализовать функцию bool USBID::operator ==(USBID *cmpId) const
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
surendil
Гость
« Ответ #2 : Август 19, 2011, 00:33 »

Всё равно не работает Плачущий А я правильно думаю?
Код
C++ (Qt)
USBID meow(vID);
int foundIndex = m_ids->indexOf(&meow); // QList< USBID* > *m_ids;
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #3 : Август 19, 2011, 01:00 »

Вам был бы нужен был бы оператор
bool operator == ( const MyString * cmpId, const MyString * cmpId2 );
Но оператор с 2 ссылками перегрузить вам не удастся.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #4 : Август 19, 2011, 01:08 »

Всё равно не работает Плачущий А я правильно думаю?
Код
C++ (Qt)
USBID meow(vID);
int foundIndex = m_ids->indexOf(&meow); // QList< USBID* > *m_ids;
если meow - это какая-то локальная переменная, то она получит новый адрес, которого точно нету в m_ids (а если вдруг такой адрес там и найдется, то он все равно будет указывать на другой объект)
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #5 : Август 19, 2011, 01:10 »

kambala, я думаю он хотел перегрузить оператор ==, что бы сравнивались не указатели, а то, на что они указывают.
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #6 : Август 19, 2011, 01:28 »

Впринципе вместо указателя можно использовать класс (самописный или существующий).

Нечто вроде:
Код
C++ (Qt)
bool operator ==( const QPointer< USBID > &cmpId, const QPointer< USBID > &cmpId2 )
{
   return *cmpId == *cmpId2;
}
 
USBID meow(vID);
int foundIndex = m_ids->indexOf(&meow); // QList< QPointer< USBID > > *m_ids;

Примечание 1: QPointer требует чтобы USBID наследовалось от QObject.
Примечание 2: Я бы на вашем месте отказался от QList::indexOf.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #7 : Август 19, 2011, 01:30 »

да, точно Улыбающийся

тогда если объекты типа USBID и так где-то хранятся, почему бы не хранить их прямо в QList<USBID>?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
surendil
Гость
« Ответ #8 : Август 19, 2011, 01:44 »

И правда, классы изначально кривые, отсюда и сложности.
Спасибо вам за советы, утром буду пробовать ^_^
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Август 19, 2011, 03:00 »

indexOf - всего лишь линейный перебор, да и нет смысла его переопределять - напр он может потребоваться для нахождения указателя. Иногда продуктивен подход типа "да чихал я на Ваши функторы!", напр

Код
C++ (Qt)
template <class T1, class T2>
int IndexOfValue( const T1 & src, const T2 & match )
{
for (int i = 0; i < src.size(); ++i)
 if (*src[i] == match)
  return i;
return -1;
}
 
Записан
surendil
Гость
« Ответ #10 : Август 19, 2011, 10:36 »

Я отказался от затеи с QList Веселый получилось так:

Код
C++ (Qt)
class USBIDs
{
// ...
public:
 bool findDevice(const QString &vID, const QString &pID);
 QString vendorName() const
 QString productName() const;
 
private:
 QHash< QString, USBInfo > *m_ids;
 QString m_selectedKey;
};
Код
C++ (Qt)
bool USBIDs::findDevice(const QString &vID, const QString &pID)
{
 m_selectedKey = vID + pID;
 return m_ids->contains(m_selectedKey);
}
 
QString USBIDs::vendorName() const  { return m_ids->value(m_selectedKey).vendorName; }
QString USBIDs::productName() const { return m_ids->value(m_selectedKey).productName; }
« Последнее редактирование: Август 19, 2011, 10:38 от surendil » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Август 19, 2011, 20:30 »

Я отказался от затеи с QList Веселый получилось так:
m_selectedKey. xорошего впечатления не производит Улыбающийся  Потом если Вам понадобится выводить поля USBInfo в определенном порядке, то нужен будет еще контейнер. А вот завернуть все поиски в USBIDs - идейка неплохая, может действовать примерно так

Код
C++ (Qt)
struct USBIDs : public QList <USBInfo> {
typedef QList <const USBInfo *> TUSBListPtr;
TUSBListPtr Lookup( const QString * vendorName, const QString * productName, int options ) const;
 
TUSBListPtr LookupByVendor( const QString & vendorName, int options = look_FullMatch  ) const;
{
 return Lookup(&vendorName, 0, options);
}
 
TUSBListPtr LookupByProduct( const QString & productName, int options = look_FullMatch  ) const;
{
 return Lookup(0, &productName, options);
}
 
enum {
 look_FullMatch = 0,
 look_StartsWith = 1,
 look_EndsWith = 2,
};
};
 
Записан
surendil
Гость
« Ответ #12 : Август 20, 2011, 10:31 »

Чёрт, я ничего не понял Веселый Igors, можете в двух словах пояснить ваш пример? Пожалуйста ^^
Upd: кажется, чуть-чуть понял. А почему m_selectedKey было плохо?
« Последнее редактирование: Август 20, 2011, 10:33 от surendil » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Август 20, 2011, 13:33 »

Чёрт, я ничего не понял Веселый Igors, можете в двух словах пояснить ваш пример? Пожалуйста ^^
Upd: кажется, чуть-чуть понял. А почему m_selectedKey было плохо?
Вообще-то наследоваться от контейнера часто нехорошо, но здесь, мне кажется, нормально.  Насчет m_selectedKey - ну а как Вы его будете пользовать?
Код
C++ (Qt)
if (uids.findDevice(vendor, product)) {
// а здесь что?
return uids.vendorName();  // нет смысла, это тот самый vendor  
}
 
Напр потребуется подсчитать (или показать) все продукты такого-то vendora - и что, опять класс делать? Разумно выглядит зарядить все выборки в одном месте, пусть пока 1, по мере необходимости будете расширяться внутри класса
Код
C++ (Qt)
TUSBListPtr lst = uids.LookupByVendor(vendor);
 
// теперь по каждому USB этого vendora
for (int  i = 0; i < lst.size(); ++i)
  // печатаем, выводим и.т.п.
}
 
Записан
surendil
Гость
« Ответ #14 : Август 21, 2011, 00:38 »

Я подумал и остановился на ассоциативных массивах. Получилось плоско, но вроде бы попроще Улыбающийся
Код
C++ (Qt)
class USBID_Vendor
{
// ...
private:
 QString _name
 QHash< QString, QString > _products; // ID, Name
};
Код
C++ (Qt)
class USBIDs
{
// ...
private:
 QHash< QString, USBID_Vendor > _ids
};
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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