Russian Qt Forum

Qt => Общие вопросы => Тема начата: SASA от Март 09, 2011, 19:37



Название: Наследование от QList.
Отправлено: SASA от Март 09, 2011, 19:37
Решил сделать контейнер аля QStringList.

Код:
class CMyClassList : public QList<CMyClass>
{
...
}

Проблема 1. Реализация должна быть в h-файле. Причем, если используется внутри библиотеки  - можно и в cpp, а если экспортируется, то нельзя. Кто-нибудь знает почему?

Проблема 2. У QList нет метода, возвращающего T&. Поэтому в методах CMyClassList приходится писать (*this)[_i]. Или сделать функцию
Код:
inline CMyClass & CMyClassList::resultAt(int _i)
{
return (*this)[_i];
}
То ли троли забыли, то ли наследоваться от QList это плохо.


Название: Re: Наследование от QList.
Отправлено: Пантер от Март 09, 2011, 20:36
А зачем наследоваться от QList?


Название: Re: Наследование от QList.
Отправлено: Akon от Март 09, 2011, 22:32
typedef QList<CMyClass> CMyClassList;
Может это все что нужно?


Название: Re: Наследование от QList.
Отправлено: SASA от Март 10, 2011, 00:22
typedef QList<CMyClass> CMyClassList;
Может это все что нужно?
Сначала было так. Но потом начали появляться операции над всеми элементами контейнера. Например, вызвать определённый метод. Думал сделать QList членом класса, но CMyClassList - контейнер, и используется как контейнер. Наследование самое оно.
А зачем наследоваться от QList?
Например, QstrinList.


Название: Re: Наследование от QList.
Отправлено: Пантер от Март 10, 2011, 08:16
Неверным путем идешь, товарищ. :)
Определенный метод для всем лучше сделать через стандартные алгоритмы и свой функтор.


Название: Re: Наследование от QList.
Отправлено: SASA от Март 10, 2011, 09:01
Неверным путем идешь, товарищ. :)
Определенный метод для всем лучше сделать через стандартные алгоритмы и свой функтор.

Не понял.


Название: Re: Наследование от QList.
Отправлено: Пантер от Март 10, 2011, 10:06
Образный пример:
Код
C++ (Qt)
CMyClass {
.........
public:
  void someFunction ();
.........
}
...................
struct CMyClassFunctor {
void operator() (CMyClass *c) {c->someFunction ();}
}
.............
QList <CMyClass*> list;
std::for_each (list.begin(), list.end(), CMyClassFunctor ());


Название: Re: Наследование от QList.
Отправлено: alexman от Март 10, 2011, 10:50
Пантер, что же плохого в насдовании?


Название: Re: Наследование от QList.
Отправлено: Пантер от Март 10, 2011, 11:59
Отвечу вопросом на вопрос: а зачем оно в данном случае? Бритва Оккама (http://ru.wikipedia.org/wiki/%D0%91%D1%80%D0%B8%D1%82%D0%B2%D0%B0_%D0%9E%D0%BA%D0%BA%D0%B0%D0%BC%D0%B0)


Название: Re: Наследование от QList.
Отправлено: SASA от Март 10, 2011, 12:20
Образный пример:
Код
C++ (Qt)
std::for_each (list.begin(), list.end(), CMyClassFunctor ());

Суть в том, что бы избавиться от таких конструкций по всему коду. Отличий от цикла, проходящего по всем элементам, не много.

И 10 функторов смотрятся "хуже", чем 10 методов одного класса. А если два таких списка?


Название: Re: Наследование от QList.
Отправлено: Пантер от Март 10, 2011, 12:24
Тогда лучше QList агрегировать в свой класс. Не нужно наследоваться от классов, которые не созданы для наследования.


Название: Re: Наследование от QList.
Отправлено: Авварон от Март 10, 2011, 12:32
не понял, oprator[] же возвражает норм ссылку, а at() конст ссылку.


Название: Re: Наследование от QList.
Отправлено: Igors от Март 10, 2011, 12:40
Тогда лучше QList агрегировать в свой класс. Не нужно наследоваться от классов, которые не созданы для наследования.
Ну как сказать. С одной стороны вроде да, все можно делать теми "функторами". А с другой - ну так оно неряшливо смотрится, что желание Sasa иметь "человеческий" класс очень понятно. Откуда у Вас взялся CMyClass? Чему он служит кроме "функтора"? Отож.


Название: Re: Наследование от QList.
Отправлено: Пантер от Март 10, 2011, 12:46
Если наследуешься от класса, который для этого не предназначен, можешь огрести косяков. А на счет неряшливости я что-то совсем не понял. Если именно о "красивости" хедера идет разговор, то лучше всего заюзать пимпл.


Название: Re: Наследование от QList.
Отправлено: Авварон от Март 10, 2011, 13:08
наследовался от кулиста косяков не было. предназначен наследоваться, не предназначен - какая разница


Название: Re: Наследование от QList.
Отправлено: Пантер от Март 10, 2011, 13:14
Такая, что деструктор не обязательно виртуальный, внутренности (private) скрыты и что в них - хз (т.е. нету полного контроля над внутренней реализацией), protected в большинстве отсутствует.


Название: Re: Наследование от QList.
Отправлено: Авварон от Март 10, 2011, 13:17
класс будет жить на стеке и виртуальный дестр ему не нужен


Название: Re: Наследование от QList.
Отправлено: Пантер от Март 10, 2011, 13:18
Ога. Это типа такое ограничение? А вдруг забуду и сделаю его в куче? Т.е. захочу удалить через указатель на QList.


Название: Re: Наследование от QList.
Отправлено: GreatSnake от Март 10, 2011, 13:20
Цитировать
Если наследуешься от класса, который для этого не предназначен, можешь огрести косяков.
Чего-то я тоже не понимаю, что плохого в наследовании от QList?


Название: Re: Наследование от QList.
Отправлено: Авварон от Март 10, 2011, 13:21
Ога. Это типа такое ограничение? А вдруг забуду и сделаю его в куче? Т.е. захочу удалить через указатель на QList.
то ты перейдешь в разряд быдлокодеров. Нахрена майлист кастить к базовому классу?


Название: Re: Наследование от QList.
Отправлено: SASA от Март 10, 2011, 13:38
не понял, oprator[] же возвражает норм ссылку, а at() конст ссылку.
Ну, и в методах получается

Код:
oprator[](i).blabla()

Мало того, что выглядит страшно, так она ещё подсвечивается в IDE не как метод.

Цитировать
Тогда лучше QList агрегировать в свой класс.

В коде этот класс используется как контейнер. Можно, конечно, переопределить кучу методов, да так, чтоб не ошибиться с со всякими const, &, << и т.д. Долго и ошибкоопастно.


Название: Re: Наследование от QList.
Отправлено: kirill от Март 10, 2011, 16:45
Вот здесь я делаю такой изврат:
http://qtcoder.blogspot.com/2010/02/directmap-map.html (http://qtcoder.blogspot.com/2010/02/directmap-map.html)

Код
C++ (Qt)
template <class Key, class Value>
class DirectMap : private QList<QPair<Key, Value> >
{
public:
 //! Добавляем пару
 void append(const Key &, const Value &);
 //! Список ключей
 QList<Key> keys() const;
 //!
 Value operator[](const Key & key) const;
};
 
 
 


Название: Re: Наследование от QList.
Отправлено: m_ax от Март 10, 2011, 17:02
Вот здесь я делаю такой изврат:
http://qtcoder.blogspot.com/2010/02/directmap-map.html (http://qtcoder.blogspot.com/2010/02/directmap-map.html)

Код
C++ (Qt)
template <class Key, class Value>
class DirectMap : private QList<QPair<Key, Value> >
{
public:
 //! Добавляем пару
 void append(const Key &, const Value &);
 //! Список ключей
 QList<Key> keys() const;
 //!
 Value operator[](const Key & key) const;
};
 
 
 

А зачем дублировать информацию о ключах, ведь её можно извлечь из  QList<QPair<Key, Value> >?
И почему просто не воспользоваться QMap?

Ой, совсем брежу)) QList - эт ж не член)) Первый вопрос решён))


Название: Re: Наследование от QList.
Отправлено: twp от Март 10, 2011, 17:14
по второму вопросу можно узнать ответ, прочитав каменты по той ссылке, что приведена перед фрагментом кода


Название: Re: Наследование от QList.
Отправлено: m_ax от Март 10, 2011, 17:18
по второму вопросу можно узнать ответ, прочитав каменты по той ссылке, что приведена перед фрагментом кода
Ясненько)


Название: Re: Наследование от QList.
Отправлено: Igors от Март 10, 2011, 17:39
А чего это "ссылка" производит такое магическое действие?  :) Я вот читаю и не врубаюсь

Цитировать
Недостаток ассоциативного массива QMap в том, что в нем ключи упорядочиваются. Т.е. если я добавлю в QMap" Key2", "Key1", то на выходе получу, сюрприз, "Key1", "Key2". Ключи будут отсортированы.
Такое поведение честно говоря подзае..ло, а альтернативы в Qt нету.
На то он и map (красно-черное дерево) чтобы автоматом упорядочиваться, зачем называть это недостатком?

Цитировать
В качестве альтернативы они предлагают использовать QList<QPair<>>. Крайне громоздкая структура.
Наконец я решил сделать класс с удобством пользования как у QMap и с функционалом как у QList, т.е. без автоматического упорядочивания по ключам.
..
template <class Key, class Value>
Value DirectMap<Key, Value>::operator[](const Key & key) const
{
  for (int i = 0; i < QList::count(); ++i)
  {
   if (QList::at(i).first == key)
   {
     return QList::value(i).second;
   }
  }
  return Value();
}
Не жирно ли будет работать линейным перебором? Если "так надо" то с тем же успехом можно задействовать любой контейнер прямого доступа, а прятать это в операторе [] - никак не гуд. Если я чего-то не понял - поясните.


Название: Re: Наследование от QList.
Отправлено: kirill от Март 11, 2011, 10:43
Цитировать
Недостаток ассоциативного массива QMap в том, что в нем ключи упорядочиваются. Т.е. если я добавлю в QMap" Key2", "Key1", то на выходе получу, сюрприз, "Key1", "Key2". Ключи будут отсортированы.
Такое поведение честно говоря подзае..ло, а альтернативы в Qt нету.
На то он и map (красно-черное дерево) чтобы автоматом упорядочиваться, зачем называть это недостатком?

Ну не недостаток.
Я хочу мап, в котором ключи не упорядочиваются.

Цитировать
В качестве альтернативы они предлагают использовать QList<QPair<>>. Крайне громоздкая структура.
Наконец я решил сделать класс с удобством пользования как у QMap и с функционалом как у QList, т.е. без автоматического упорядочивания по ключам.
..
template <class Key, class Value>
Value DirectMap<Key, Value>::operator[](const Key & key) const
{
  for (int i = 0; i < QList::count(); ++i)
  {
   if (QList::at(i).first == key)
   {
     return QList::value(i).second;
   }
  }
  return Value();
}
Не жирно ли будет работать линейным перебором? Если "так надо" то с тем же успехом можно задействовать любой контейнер прямого доступа, а прятать это в операторе [] - никак не гуд. Если я чего-то не понял - поясните.
[/quote]

Согласен, код неоптимален, но общая идея как раз в том, чтобы спрятать в операторе [] процесс доступа к данным.