crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Свои объекты в QSet
Andrewshkovskii
  опции профиля:
сообщение 22.11.2009, 2:01
Сообщение #1


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Цитата
QSet's value data type must be an assignable data type. You cannot, for example, store a QWidget as a value; instead, store a QWidget *. In addition, the type must provide operator==(), and there must also be a global qHash() function that returns a hash value for an argument of the key's type. See the QHash documentation for a list of types supported by qHash().

Цитата
The values stored in the various containers can be of any assignable data type. To qualify, a type must provide a default constructor, a copy constructor, and an assignment operator. This covers most data types you are likely to want to store in a container, including basic types such as int and double, pointer types, and Qt data types such as QString, QDate, and QTime, but it doesn't cover QObject or any QObject subclass (QWidget, QDialog, QTimer, etc.). If you attempt to instantiate a QList<QWidget>, the compiler will complain that QWidget's copy constructor and assignment operators are disabled. If you want to store these kinds of objects in a container, store them as pointers, for example as QList<QWidget *>.


Я так понимаю, что для того, что бы можно было хранить свои объекты в сетах, необходимо что бы у объекта были определены :
Оператор сравнения.
Конструктор копирования.
Конструктор по-умолчанию.
И ..самое страшное, что бы была определена глобальная функция qHash для своего типа данных?

Ну 3ое три то понятно, а вот насчет хэша?..это исходник QHash дописывать, что ли, придется?

Вот пока что есть :

Раскрывающийся текст
#ifndef CLUSTER_H
#define CLUSTER_H
#include <QSet>
#include <QPoint>
#include <QString>
#include <QStringList>

class Cluster
{
private :
int value_;
QSet<int> items_;
QPoint centerPos;
bool isPainted;
public :
Cluster();
Cluster(const Cluster & other);
Cluster(int item1 ,int item2, int nValue);
Cluster(int item1, int nValue);
void setValue(int newValue);
int value(){ return value_; }
QSet<int> &items() {return items_;}
QSet <Cluster> itemsToSet();
void setPainted(bool is);
QString toString(QStringList * lst);
void append(Cluster * nClust);
bool operator ==(const Cluster &other);
};

#endif // CLUSTER_H


и реализация :
Раскрывающийся текст

#include "cluster.h"

Cluster::Cluster()
{
}

Cluster::Cluster(const Cluster &other)
{
    items_=other.items();
    value_=other.value();
}

Cluster::Cluster(int item1 , int item2, int nValue)
{
   value_=nValue;
   items_.insert(item1);
   items_.insert(item2);
}

Cluster::Cluster(int item1 , int nValue)
{
   value_=nValue;
   items_.insert(item1);
}

bool Cluster::operator ==(const Cluster& other)
{
    return (items_==other.items() && value_==other.value());
}

void Cluster::setValue(int newValue)
{
    value_=newValue;
}

QString Cluster::toString(QStringList * lst)
  {
   QString str;
   QStringList * list = lst;
   QSetIterator <int> it (items_);
   str.append("|");
   while(it.hasNext())
       str.append(list->at(it.next())+" ");
   str.append("|");
   return str;
   }

void Cluster::append(Cluster * nClust)
{
   QSetIterator <int> it (nClust->items());
    while (it.hasNext())
        items_ << it.next();
}

void Cluster::setPainted(bool is)
{
    isPainted=is;
}

QSet <Cluster *> Cluster::itemsToSet()
{
    QSet <Cluster> retSet;
    QSetIterator <int> it(items_);
    while(it.hasNext())
        retSet.insert(Cluster(it.next(),0));
    return retSet;
}


и тысячи ошибок от QSTL, но вот основные стопы в этом :
Цитата
C:/storage/programming/workspace/clusters/../../Qt/include/QtCore/../../src/corelib/tools/qhash.h:855: error: no matching function for call to 'qHash(const Cluster&)'


Цитата
C:/storage/programming/workspace/clusters/../../Qt/include/QtCore/../../src/corelib/tools/qhash.h:855: error: no matching function for call to 'qHash(const Cluster&)
Почему-то вот для этой функции
  inline bool same_key(uint h0, const Key &key0) { return h0 == h && key0 == key; }

'


Так чтоже мне делать? писать qHash для своего объекта и что ещё?

и ещё, вопрос из-за не достаточного знания C++,
есть в этом классе такой метод :

 const QSet<int> &items() {return items_;}


Почему, когда я пытаюсь сделать вот так вот :
if (!(ribs.at(k)->items() &= ribs.at(l)->items()).empty())

ribs это QVector <Cluster *>;
то получаю
error: passing 'const QSet<int>' as 'this' argument of 'QSet<T>& QSet<T>::operator&=(const QSet<T>&) [with T = int]' discards qualifiers


Что вообще обозначает данная ошибка?
Просто мне в проверках условиях не нужно менять содержимое Set'ов объекта Cluster, а оно из-за возвращения не константной ссылки меняется.Можно конечно возвращать копию, но это расход памяти...
Заранее спасибо..

Сообщение отредактировал Andrewshkovskii - 22.11.2009, 3:04
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.11.2009, 3:14
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Andrewshkovskii @ 22.11.2009, 5:01) *
Я так понимаю, что для того, что бы можно было хранить свои объекты в сетах, необходимо что бы у объекта были определены :
читай по-русски, там понятнее.
Там же написано, как QWidget использовать, хотя он и не предоставляет конструктор копирования

Цитата(Andrewshkovskii @ 22.11.2009, 5:01) *
а вот насчет хэша?..это исходник QHash дописывать, что ли, придется?
смотри описание класса QHash, там есть пример собственного класса Employee и соответствующей функции qHash
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 22.11.2009, 11:36
Сообщение #3


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Цитата(Litkevich Yuriy @ 22.11.2009, 3:14) *
Цитата(Andrewshkovskii @ 22.11.2009, 5:01) *
Я так понимаю, что для того, что бы можно было хранить свои объекты в сетах, необходимо что бы у объекта были определены :
читай по-русски, там понятнее.
Там же написано, как QWidget использовать, хотя он и не предоставляет конструктор копирования

Цитата(Andrewshkovskii @ 22.11.2009, 5:01) *
а вот насчет хэша?..это исходник QHash дописывать, что ли, придется?
смотри описание класса QHash, там есть пример собственного класса Employee и соответствующей функции qHash


Использование указателей мне не поможет в данном случае, а вот насчет примера в QHash спасибо, что-то не заметил.
А вот что насчет 2го вопроса про QSet и операции над множествами?
=========
Написал всё что нужно для сравнения в хэще, только одна проблема:
мне надо сравнить 2 поля класса, и оба поля QSet<int>, а хэш поддерживает только простые типы данных.как же быть в этом случае, во что преобразовать этот QSet? Может попробовать брать от каждого элемента Set'a хэш, ксорить их, и возврашать хэш?

Сообщение отредактировал Andrewshkovskii - 22.11.2009, 13:23
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.11.2009, 13:57
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Andrewshkovskii @ 22.11.2009, 5:01) *
if (!(ribs.at(k)->items() &= ribs.at(l)->items()).empty())
запиши проще:
if (!(A &= B))

что делает оператор &=?
Это оператор сравнения?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 22.11.2009, 14:05
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Пересечение множеств, только вот одно но, он всераво изменяет левый объект, вот так вот :
Цитата
QSet<T> & QSet::operator&= ( const QSet<T> & other )

Same as intersect(other).

See also operator&(), operator|=(), and operator-=().


Цитата
QSet<T> & QSet::intersect ( const QSet<T> & other )

Removes all items from this set that are not contained in the other set. A reference to this set is returned.

See also operator&=(), unite(), and subtract().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.11.2009, 14:10
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Andrewshkovskii @ 22.11.2009, 17:05) *
Пересечение множеств
НЕТ! (т.к. я не указывал, что аргументами являются множества)
Посмтри, где-нибудь про такие операторы в Си/Си++:
+=
-+
*=
/=
&=
|=
Узнай что они означают.

П.С. "пересечение множеств" это частный смысл какой-либо математической операции.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 22.11.2009, 14:13
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Видимо Ты немного не понял контекст, items() возвращает QSet<int>, в данном случае, это и будет пересечение одного множества на другое(левого с правым) и возвращение ссылки на измененное левое множество(вроде так).
А оператор &= ,насколько я помню, для стандартных типов выполняет либо присваение ссылки, либо адреса левой переменной от правой.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 22.11.2009, 14:22
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Andrewshkovskii @ 22.11.2009, 17:13) *
Видимо Ты немного не понял контекст
да причём здесь контекст?
У операторов типа +=
совершенно определённый смысл.
A += B
тоже, что и
A = A + B
Аналогично:
A &= B
тоже, что и
A = A & B
И что ты сделал:
if (! (A = A & B ))
, т.е. ты делаешь явное присваниавание и при этом говоришь, что тебе оно не нужно.
Как тебя понимать?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Andrewshkovskii
  опции профиля:
сообщение 22.11.2009, 14:29
Сообщение #9


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Контекст..
Смотри, в любом случае будет присваение левому нового значения от операции &=, т.к для QSet, операция пересечения определена 2 методами :
1.
Цитата
QSet<T> & QSet::intersect ( const QSet<T> & other )

Removes all items from this set that are not contained in the other set. A reference to this set is returned.

See also operator&=(), unite(), and subtract().


2.
Цитата
QSet<T> & QSet::operator&= ( const QSet<T> & other )

Same as intersect(other).

See also operator&(), operator|=(), and operator-=().


И, насколько я понимаю, нету возможности проверить, есть ли пересечения у 2х множест не изменив одно из них.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DIMEDROLL
  опции профиля:
сообщение 22.11.2009, 23:20
Сообщение #10


Участник
**

Группа: Участник
Сообщений: 165
Регистрация: 28.9.2008
Из: Киев
Пользователь №: 304

Спасибо сказали: 23 раз(а)




Репутация:   0  


Цитата(Andrewshkovskii @ 22.11.2009, 1:01) *
Почему, когда я пытаюсь сделать вот так вот :

if (!(ribs.at(k)->items() &= ribs.at(l)->items()).empty())


ribs это QVector <Cluster *>;
то получаю

error: passing 'const QSet<int>' as 'this' argument of 'QSet<T>& QSet<T>::operator&=(const QSet<T>&) [with T = int]' discards qualifiers



Что вообще обозначает данная ошибка?


Ошибка означает, что ты пытаешься изменить константный обьект. Когда ты пишешь
ribs.at(k)->items()

то получаешь:
const QSet<int>

и у этого вызываешь оператор &=, который изменяет обьект. Используй оператор & и будет работать все как надобно:
if (!(ribs.at(k)->items() & ribs.at(l)->items()).empty())

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 22.11.2019, 6:10