Russian Qt Forum

Qt => Вопросы новичков => Тема начата: sibmail от Апрель 04, 2012, 07:41



Название: Как описать матрицу из различных типов
Отправлено: sibmail от Апрель 04, 2012, 07:41
ПОдскажите как описать матрицу из различных типов. если например матрица будет фиксированная или динамическая, состоящая из int, QString, QByteArray и т.д.


Название: Re: Как описать матрицу из различных типов
Отправлено: Dovgon от Апрель 04, 2012, 07:56
используй QVarian


Название: Re: Как описать матрицу из различных типов
Отправлено: Bepec от Апрель 04, 2012, 07:56
QVariant используй. Ну или отрекись от разных типов в пользу структур ;)


Название: Re: Как описать матрицу из различных типов
Отправлено: Igors от Апрель 04, 2012, 12:24
Код
C++ (Qt)
template <class T>
struct CMatrixDynamic {
CMatrixDynamic( int row, int col );
...
T * mData;
};
 
template <class T, int kRow, int kCol>
struct CMatrixStatic {
...
T mData[kRow][kCol];
};
 


Название: Re: Как описать матрицу из различных типов
Отправлено: mutineer от Апрель 04, 2012, 12:31
Igors, как это поможет хранить разные типы в одном контейнере?


Название: Re: Как описать матрицу из различных типов
Отправлено: Igors от Апрель 04, 2012, 12:44
Igors, как это поможет хранить разные типы в одном контейнере?
Никак, но зачем делать "матрицу" элементы которой имеют разный тип? Вероятно человек спросил как делать общую матрицу для разных типов. Иначе он бы сказал "контейнер"


Название: Re: Как описать матрицу из различных типов
Отправлено: m_ax от Апрель 04, 2012, 12:52
Один фиг, всегда можно сделать вот так:
Код
C++ (Qt)
Matrix<QVariant, N, M> matrix;
 
;)


Название: Re: Как описать матрицу из различных типов
Отправлено: Igors от Апрель 04, 2012, 12:59
Один фиг, всегда можно сделать вот так:
Код
C++ (Qt)
Matrix<QVariant, N, M> matrix;
 
;)
А как уложить static/dynamic в одну template конструкцию? Или это лишено смысла?


Название: Re: Как описать матрицу из различных типов
Отправлено: m_ax от Апрель 04, 2012, 13:01
Цитировать
А как уложить static/dynamic в одну template конструкцию? Или это лишено смысла?
Не понял.. В смысле?


Название: Re: Как описать матрицу из различных типов
Отправлено: Igors от Апрель 04, 2012, 13:14
Цитировать
А как уложить static/dynamic в одну template конструкцию? Или это лишено смысла?
Не понял.. В смысле?
Пример
Код
C++ (Qt)
void CStaticMatrix<T>::Transpose( void );
void CDynamicMatrix<T>::Transpose( void );
 
Transpose меняет строки со столбцами, этот код совершенно одинаков для статического и динамического вариантов. Обобщаем или как?


Название: Re: Как описать матрицу из различных типов
Отправлено: m_ax от Апрель 04, 2012, 13:23
Так не надо делать transpose методом класса, тем более который подменяет изначальную матрицу на другую..

Или сделать так, чтоб transpose возвращала новую транспонированную матрицу. Конечно, если делать так в лоб, это будет не очень оптимально, но если подумать)


Название: Re: Как описать матрицу из различных типов
Отправлено: V1KT0P от Апрель 04, 2012, 13:28
Igors, как это поможет хранить разные типы в одном контейнере?
Никак, но зачем делать "матрицу" элементы которой имеют разный тип? Вероятно человек спросил как делать общую матрицу для разных типов. Иначе он бы сказал "контейнер"
По-моему автор неправильно выразился. И сделать матрицу который имеют разный тип не проблема. Для этого надо привести указатель типа к обычному int и получаем матрицу указателей. Ну а при вытаскивании динамик каст используем, либо если в матрице хранить идентификатор типа то и статик каст пойдет.


Название: Re: Как описать матрицу из различных типов
Отправлено: mutineer от Апрель 04, 2012, 13:31
По-моему автор неправильно выразился. И сделать матрицу который имеют разный тип не проблема. Для этого надо привести указатель типа к обычному int и получаем матрицу указателей. Ну а при вытаскивании динамик каст используем, либо если в матрице хранить идентификатор типа то и статик каст пойдет.

А почему к "обычному" int? Почему не к "обычному" QPushButton, например?:)
и сколько кастов надо сделать, прежде чем понять что же за тип такой вытащился?


Название: Re: Как описать матрицу из различных типов
Отправлено: m_ax от Апрель 04, 2012, 13:32
Igors, как это поможет хранить разные типы в одном контейнере?
Никак, но зачем делать "матрицу" элементы которой имеют разный тип? Вероятно человек спросил как делать общую матрицу для разных типов. Иначе он бы сказал "контейнер"
По-моему автор неправильно выразился. И сделать матрицу который имеют разный тип не проблема. Для этого надо привести указатель типа к обычному int и получаем матрицу указателей. Ну а при вытаскивании динамик каст используем, либо если в матрице хранить идентификатор типа то и статик каст пойдет.
Я бы не рискнул хранить в матрице указатели (если она динамически может меняться)..

И на самом деле, почему int?


Название: Re: Как описать матрицу из различных типов
Отправлено: V1KT0P от Апрель 04, 2012, 13:36
Igors, как это поможет хранить разные типы в одном контейнере?
Никак, но зачем делать "матрицу" элементы которой имеют разный тип? Вероятно человек спросил как делать общую матрицу для разных типов. Иначе он бы сказал "контейнер"
По-моему автор неправильно выразился. И сделать матрицу который имеют разный тип не проблема. Для этого надо привести указатель типа к обычному int и получаем матрицу указателей. Ну а при вытаскивании динамик каст используем, либо если в матрице хранить идентификатор типа то и статик каст пойдет.
Я бы не рискнул хранить в матрице указатели (если она динамически может меняться)..

И на самом деле, почему int?
Размер указателя равен intу =). Если добавить еще одну матрицу в которой хранится идентификатор типа, то хватит одного статик каста для привидения к нужному типу =).
Надо подождать пока автор уточнит что он хочет. А то может он хочет сделать игру и все объекты на карте хранить в матрице, тогда ему нужен базовый класс, а остальные наследовать от него. И тогда будет матрица базового класса.


Название: Re: Как описать матрицу из различных типов
Отправлено: mutineer от Апрель 04, 2012, 13:38
Размер указателя равен intу =). Если добавить еще одну матрицу в которой хранится идентификатор типа, то хватит одного статик каста для привидения к нужному типу =).
Надо подождать пока автор уточнит что он хочет. А то может он хочет сделать игру и все объекты на карте хранить в матрице, тогда ему нужен базовый класс, а остальные наследовать от него. И тогда будет матрица базового класса.

Кастовать указатель к int?о_О Зачем?О_о
Идентификатор типа... Это при вытаскивании будет такой большой свитч с кастами в зависимости от идентификатора?

Ну и очень интересно как ты int будешь кастовать к указателю при помощи dynamic_cast


Название: Re: Как описать матрицу из различных типов
Отправлено: kambala от Апрель 04, 2012, 13:43
Ну и очень интересно как ты int будешь кастовать к указателю при помощи dynamic_cast
reinterpret_cast :)

по-моему автору нужно обычное решение через шаблоны, которое уже было предложено выше. а хранить разные типы в контейнере - это немного извращение как по мне.


Название: Re: Как описать матрицу из различных типов
Отправлено: V1KT0P от Апрель 04, 2012, 13:44
Размер указателя равен intу =). Если добавить еще одну матрицу в которой хранится идентификатор типа, то хватит одного статик каста для привидения к нужному типу =).
Надо подождать пока автор уточнит что он хочет. А то может он хочет сделать игру и все объекты на карте хранить в матрице, тогда ему нужен базовый класс, а остальные наследовать от него. И тогда будет матрица базового класса.

Кастовать указатель к int?о_О Зачем?О_о
Идентификатор типа... Это при вытаскивании будет такой большой свитч с кастами в зависимости от идентификатора?
Ну а ты сам подумай если мы вытянули тип из матрицы то для его обработки полюбому нужен свой код. Например можно сделать массив указателей на функции которые принимают int, а в них уже будет статик каст и дальнейшая обработка типа =).
То-есть берем число из матрицы идентификаторов и вызываем функцию через указатель на функцию и передаем туда число из матрицы типов, в этой функции уже будет статик каст и дальнейшая обработка типа.
Для каждого типа по-любому должна быть своя функция =). Вечером могу даже набросать рабочий пример, если кому-то такое извращение нравится =).


Название: Re: Как описать матрицу из различных типов
Отправлено: Igors от Апрель 04, 2012, 13:50
Размер указателя равен intу =).
Давно уже не равен (в 64 битах указатель 8 а int 4). И, как уже сказал mutineer, вытаскивать там придется долго и мучительно. И не цивильным dynamic_cast, а грубым reinterpret. С этой точки зрения лучше QVariant (хотя такое "пастбище" на готовых классах капитально разлагает).

Так не надо делать transpose методом класса, тем более который подменяет изначальную матрицу на другую..
Ну да, если Transpose просто ф-ция принимающая template аргумент - все прекрасно. Но все же - что плохого что это метод класса? А то как-то получается - вроде сделал класс, а потом еще и "какие-то ф-ции". Блесните "частичной спецификацией" и.т.п. - я в этом не силен


Название: Re: Как описать матрицу из различных типов
Отправлено: V1KT0P от Апрель 04, 2012, 13:56
Размер указателя равен intу =).
Давно уже не равен (в 64 битах указатель 8 а int 4). И, как уже сказал mutineer, вытаскивать там придется долго и мучительно. И не цивильным dynamic_cast, а грубым reinterpret. С этой точки зрения лучше QVariant (хотя такое "пастбище" на готовых классах капитально разлагает).

Так не надо делать transpose методом класса, тем более который подменяет изначальную матрицу на другую..
Ну да, если Transpose просто ф-ция принимающая template аргумент - все прекрасно. Но все же - что плохого что это метод класса? А то как-то получается - вроде сделал класс, а потом еще и "какие-то ф-ции". Блесните "частичной спецификацией" и.т.п. - я в этом не силен
В некоторых 64  битах int равняется 8. Но это неважно, можно хранить не число а указатель на число, смысл останется тем-же. Грубым конечно, но от этого оно не перестанет работать =). Ага позапихивай в QVariant виджеты, кнопки, пользовательские типы =). Прийдется расширять его, а можно не расширять а тупо использовать как я сказал =).


Название: Re: Как описать матрицу из различных типов
Отправлено: m_ax от Апрель 04, 2012, 14:12
Цитировать
Ну да, если Transpose просто ф-ция принимающая template аргумент - все прекрасно. Но все же - что плохого что это метод класса? А то как-то получается - вроде сделал класс, а потом еще и "какие-то ф-ции". Блесните "частичной спецификацией" и.т.п. - я в этом не силен
Много чего плохого..
Во-первых класс матрицы обрастает всякими функциями.. Сначала вам захочется сделать transpose, потом какое нить эрмитово сопряжение прикрутить, потом ещё чего нить.. А от этого как раз стараются избавится. Не хорошо из обычного класса делать супер класс на все случаи жизни. Он должен делать только то, что он должен делать.
Посмотрите как реализован valarray, например. Для этого вектора перегружены все мат. функции и они не являются его членами. Тоже самое с классом complex..

Во-вторых, при операции транспонирования , если матрица не квадратная, возникнут проблемы.. Т.е. если её размерность задаётся изначально то всё..
Или, например, вы создали матрицу.. Провели с ней какие то операции, сделали транспос и забыли.. А потом, если где нить в другом месте не вспомнить о том, что это уже совсем другая матрица, то можно долго кусать локти и рвать волосы на голове из-за странных логических ошибок))
        


Название: Re: Как описать матрицу из различных типов
Отправлено: Igors от Апрель 04, 2012, 14:21
можно хранить не число а указатель на число, смысл останется тем-же. Грубым конечно, но от этого оно не перестанет работать =). Ага позапихивай в QVariant виджеты, кнопки, пользовательские типы =). Прийдется расширять его, а можно не расширять а тупо использовать как я сказал =).
Если Вы начнете это делать то очень быстро обнаружите что приходите к тому же что делает QVariant. Вряд ли "хранить еще одну матрицу (типов)" удачная идея - уж слишком нудно ее синхронизировать. Я бы крутил примерно так
Код
C++ (Qt)
// "универсальный" элемент
class CReference {
int mTypeID;    // идентификатор типа (никуда не денешься)
union {
  int mInt;
  float mFloat
  double mDoub;
  void * mPtr;    // что-то выше травы
};
 
bool SameType( const CReference & ) const;
 
template <class T>
void Get( T & val ) const;
 
// и еще много-много чего, такие классы обычно имеют сотни членов
};
 
Но я согласен с Вами в том плане что сделать это самому куда полезнее и интереснее чем "задействовать готовое"  :)


Название: Re: Как описать матрицу из различных типов
Отправлено: m_ax от Апрель 04, 2012, 14:29
Люди, может всё же лучше вначале спросить у ТС, что он имел в виду?
Может в задаче уже изначально известно, что например, в первом столбце всегда будут храниться объкты одного типа, во втором другого, в третьем - третьего..
Тогда возможно, не придётся делать "тупо", как предлагал товарищь V1KT0P  ;)   


Название: Re: Как описать матрицу из различных типов
Отправлено: Igors от Апрель 04, 2012, 17:09
Люди, может всё же лучше вначале спросить у ТС, что он имел в виду?
А нужен ли он?

Много чего плохого..
Во-первых класс матрицы обрастает всякими функциями..
Ну блин, наплели с 3 короба :) Я немного подумал, и вроде все прекрасно ложится в 1 класс, который из статического легко превращается "в элегантные шорты"  :)

Код
C++ (Qt)
template <class T, int kRow, int kCol>
class CMatrix {
public:
CMatrix( void ) : M(mData), mRow(kRow), mCol(kCol) {}
  ~CMatrix( void ) { if (M != mData) delete [] M; }
 
T * operator [] ( int index ) { return M + index * mCol; }
const T * operator [] ( int index ) const { return M + index * mCol; }
 
bool IsStatic ( void ) const { return M == mData; }
bool IsDynamic ( void ) const { return M != mData; }
 
void Resize( int row, int col, bool keepContent = false )
{
T * newM = new T[row * col];
if (keepContent) {
//.. copy
}
if (M != mData) delete [] M;
M = newM;
mRow = row;
mCol = col;
}
 
private:
T * M;
int mRow, mCol;
T mData[kRow * kCol];
};
 


Название: Re: Как описать матрицу из различных типов
Отправлено: m_ax от Апрель 04, 2012, 17:37
Не, ну имхо, Вы здесь слегка перемудрили..
Так у пользователя этого класса есть все шансы окончательно запутаться. Если уж объявляете, что матрица статическая (не меняет свою размерность) так и не нужно сбивать с понтологии пользователей методами resize.

Или изначально делать матрицу, которая может менять свой размер:
Код
C++ (Qt)
Matrix<double> matrix(Rows, Columns);
 
 

Но мешать во едино всё это дело.. ну очень сомнительно..


Название: Re: Как описать матрицу из различных типов
Отправлено: Igors от Апрель 04, 2012, 17:53
С точки зрения пользователя - динамическая, ведь он  может изменять размеры. А внутри класса что хочу - то и делаю. Делать "просто динамической" не очень хорошо, обычно всегда есть масса матриц никогда не меняющих свой размер. А делать 2 класса - начнутся "переливания"


Название: Re: Как описать матрицу из различных типов
Отправлено: V1KT0P от Апрель 04, 2012, 18:02
Что-то мы немного увлеклись и начали решать несуществующую задачу =). Подождите пока автор не отпишется, может ему вообще банальная вещь нужна, а он просто не так выразился.


Название: Re: Как описать матрицу из различных типов
Отправлено: m_ax от Апрель 04, 2012, 18:11
С точки зрения пользователя - динамическая, ведь он  может изменять размеры. А внутри класса что хочу - то и делаю. Делать "просто динамической" не очень хорошо, обычно всегда есть масса матриц никогда не меняющих свой размер. А делать 2 класса - начнутся "переливания"
Я бы написал просто одну динамическую матрицу) А если бы мне были нужны какие либо высоко производительные мат. расчёты с ними, то я бы использовал blitz или boost uBlas.

Если есть такие матрицы, которые никогда не меняют свой размер, то и не меняйте их размер)

Что-то мы немного увлеклись и начали решать несуществующую задачу =). Подождите пока автор не отпишется, может ему вообще банальная вещь нужна, а он просто не так выразился.
Да, это мы можем))