Russian Qt Forum

Программирование => С/C++ => Тема начата: kuzulis от Январь 19, 2009, 11:56



Название: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 11:56
Доброго дня!


к примеру есть некий объект, но в зависимости от его типа нужно соосветственно по разному создавать его "внутренности"

например в одном случае в зависимости от типа объекта (ObjType) надо иметь:
Код:
class MyObj
{
public:
 MyObj(int type);
 int getType();
 int getValue(); //т.е результат - целое
 void setType(int type);
 void setValue(int value); //т.е параметр - целое
private:
 int ObjType;
 int ObjValue; // т.е. значение - целое
}
но в другом случае в зависимости от типа объекта (ObjType) надо иметь:
Код:
class MyObj
{
public:
 MyObj(int type);
 int getType();
 bool getValue(); //т.е результат - булев
 void setType(int type);
 void setValue(bool value); //т.е параметр - булев
private:
 int ObjType;
 bool ObjValue; // т.е. значение - булево
}
т.е как мне объеденить все это в одном классе, но чтобы в зависимости от переменной type в конструкторе,
класс создавался с переменной value - целой или булевой?



Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: pastor от Январь 19, 2009, 12:00
Ну этот вопрос к Qt не относится. Это по части С++...

По теме.. Возмите книгу по С++ и почитайте про шаблоны


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 12:35
да некада :) мне б побыстрее б


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Rcus от Январь 19, 2009, 12:41
Это и есть побыстрее :) Хотите медленнее возьмите Boost::Any /*giggles*/
//а если отвлеченно интерпритировать постановку то возможно вам нужен QVariant


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 13:08
насчет QVariant - это так получится?  :

*.h
Код:
class MyObj
{
public:
 MyObj(int type);
 int getType();
 QVariant getValue(); //
 void setValue(QVariant value); //
private:
 int ObjType;
 QVariant objValue; //
}


*.cpp
Код:
MyOBj::MyObj(int type)
{
 ObjType = type;
}

QVariant MyOBj::getValue()
{
 if (type==1) then return objValue.toInt;
 if (type==2) then return objValue.toBool;
}

QVariant MyOBj::setValue(QVariant value)
{
 ObjType = value;
}





Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Rcus от Январь 19, 2009, 13:13
нет, в QVariant это уже есть :)
/*@see QVariant::type(), QVariant::value<T>()*/


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 13:15
т.е вместо:
Код:
QVariant MyOBj::getValue()
{
 if (type==1) then return objValue.toInt;
 if (type==2) then return objValue.toBool;
}

писать:
Код:
QVariant MyOBj::getValue()
{
 return objValue;
}

??


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Rcus от Январь 19, 2009, 13:17
Давайте мы не будем заниматься упражнениями в стиле Foo-Bar. Скажите какую прикладную задачу вы хотите решить и возможно ответ будет найти проще


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 13:30
Цитировать
Давайте мы не будем заниматься упражнениями в стиле Foo-Bar. Скажите какую прикладную задачу вы хотите решить и возможно ответ будет найти проще

вообщето в первом посте моем вроде как задача обрисована...

т.е имеется некий класс "регистр" (class Registr) в зависимости от его типа (например тип 1 или тип 2) значение этого регистра может
быть или bool или int ...

т.е чтобы не создавать два класса class Registr1 и class Registr2 нужно как-то сделать все в одном, и чтобы при указании в конструкторе класса типа 1 или типа 2  Registr::Registr(Register Type) происходил анализ этой переменной "Register Type" и в соответствии с ней определенным образом создавались "кишки" класса.. в частности переменная Value и ф-ции, с помощью которых можно ее прочитать и записать!

т.е если задан тип 1 - то переменная Value должна создаться типа int , и соответственно ф-я getValue должна возвратить тип int, а ф-я SetValue(Value) должна принимать параметр типа int  ...

в случае типа 2 - соответственно все bool должно быть


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Dendy от Январь 19, 2009, 13:46
В данном случае лучше не писать свой велосипед вообще, а использовать вместо него непосредственно QVariant.


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: panAlexey от Январь 19, 2009, 13:57
template <typename T> class MyObj?


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: panAlexey от Январь 19, 2009, 14:00
да некада :) мне б побыстрее б
В любой спешке виноваты блохи.
Либо они на теле, либо в голове...


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 14:01
Цитировать
В данном случае лучше не писать свой велосипед вообще, а использовать вместо него непосредственно QVariant.

т.е

Код:
QVariant Registr::getValue()
{
 return RegValue;
}

Код:
void Registr::setValue(QVariant Value)
{
 RegValue = Value;
}

а сам RegValue  объявить как QVariant ????


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 14:04
Цитировать
В любой спешке виноваты блохи.
Либо они на теле, либо в голове...

сие высказывание не несет полезной инфы! увы!


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Rcus от Январь 19, 2009, 14:12
Но все же классы контейнеров являются не самоцелью, а частью решения. Например что межает заменить класс Registr на QVariant?


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 14:18
Цитировать
Но все же классы контейнеров являются не самоцелью, а частью решения. Например что межает заменить класс Registr на QVariant?

т.е имеете ввиду наследовать от QVariant ? или я чо - то не понял :) ?

а  вообще-то первоначально класс выглядел так:

Код:
typedef enum TModbusRegisterType { rt0x, rt1x, rt3x, rt4x}


class TModbusRegister
{
public:
    TModbusRegister(TModbusRegisterType regtype);
    TModbusRegisterType getType();                                  //получить тип регистра
    quint16 getAddress();                                           //получить адрес регистра
    quint16 getValue();                                             //получить значение регистра
    void setAddress(quint16 regaddress);                            //установить адрес регистра
    void setValue(quint16 regvalue);                                //установить значение регистра !!!
private:
    TModbusRegisterType type_;
    quint16 address_;
    quint16 value_;
}


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: panAlexey от Январь 19, 2009, 14:21
Цитировать
В любой спешке виноваты блохи. Либо они на теле, либо в голове...
сие высказывание не несет полезной инфы! увы!
в принципе да.


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 14:26
и если использовать QVariant - то переписать так наверное придется:

Код:
typedef enum TModbusRegisterType { rt0x, rt1x, rt3x, rt4x}


class TModbusRegister
{
public:
    TModbusRegister(TModbusRegisterType regtype);
    TModbusRegisterType getType();                                  //получить тип регистра
    quint16 getAddress();                                           //получить адрес регистра
    QVariant getValue();                                             //получить значение регистра !!!!!!!!!!!!!!!!!!
    void setAddress(quint16 regaddress);                            //установить адрес регистра
    void setValue(QVariant regvalue);                                //установить значение регистра !!!!!!!!!!!
private:
    TModbusRegisterType type_;
    quint16 address_;
    QVariant value_;                                                //!!!!!!!!!
}


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Dendy от Январь 19, 2009, 14:29
В этом случае можно заменить value_ на QVariant. Но нужно понимать что это оверхед. Если в качестве значения не будут использоваться классы (а только bool, int, qint16 и т.п.) - вместо QVariant лучше использовать union:

Код:
class TModbusRegister
{
public:
    TModbusRegister(TModbusRegisterType regtype);
    TModbusRegisterType getType();                                  //получить тип регистра
    quint16 getAddress();                                           //получить адрес регистра
    quint16 getValue();                                             //получить значение регистра
    void setAddress(quint16 regaddress);                            //установить адрес регистра
    void setValue(quint16 regvalue);                                //установить значение регистра !!!
private:
    TModbusRegisterType type_;
    quint16 address_;
    union
    {
        bool boolValue_;
        qint16 int16Value_;
    };
}


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 19, 2009, 14:36
Цитировать
В этом случае можно заменить value_ на QVariant. Но нужно понимать что это оверхед. Если в качестве значения не будут использоваться классы (а только bool, int, qint16 и т.п.) - вместо QVariant лучше использовать union:
дадада! никаких классов в качестве значений не будет!

но непонятно с юнионами... как будут выглядеть тогда ф-ции:
Код:
quint16 getValue(); 
и
Код:
void setValue(quint16 regvalue); 

???


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Dendy от Январь 19, 2009, 14:50
Почитайте про union в интернете.


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: panAlexey от Январь 19, 2009, 15:03
но непонятно с юнионами... как будут выглядеть тогда ф-ции:
Тут (в сорцах) посмотри как сделано.
http://squirrel-lang.org/


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Tonal от Январь 20, 2009, 09:47
Но все же классы контейнеров являются не самоцелью, а частью решения. Например что межает заменить класс Registr на QVariant?
Тут имелось в виду, что непонятно зачем тебе вообще понадобились такие классы?
Зачем нужны эти классы Registr? Что с их помощью ты делаешь?
Эмулятор процессора? Калькулятор? Интерпретатор своего мегаскрипта?

Если это не учебное задание, то вполне можно под подобные задачи найти какое-нибудь удобное решение а не кодировать всё с 0 не зная языка. :)

Если же это таки задание - то имеет смысл разобраться и с объединениями и с шаблонами самостоятельно.


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 20, 2009, 10:17
Цитировать
Тут имелось в виду, что непонятно зачем тебе вообще понадобились такие классы?
Зачем нужны эти классы Registr? Что с их помощью ты делаешь?
Эмулятор процессора? Калькулятор? Интерпретатор своего мегаскрипта?

:) см. http://ru.wikipedia.org/wiki/Modbus

я просто имею "творческий" порыв сделать хоть чо-то полезное в жизни! :) а именно - эти все мои вопросы связаны с началом реализации мной некоего "велосипеда" SCADA системы :)

кроме класса "регистр" - планирую сделать класс "контроллер" и потом класс "канал"...

т.е в канале имеются контроллеры  - а в контроллерах регистры!

структура такая:

модуль ---> канал1 ---> контроллер1 ---> регистры 4х
            |                   |--> контроллер2 ---> регистры 4х
            |                                                |--> регистры 3х
            |--> канал2 ---> контроллер1 ---> регистры 4х
...........................................................................................
...........................................................................................
...........................................................................................

и т.п.
 
это все реализация "модуля" Modbus !!!

1. регистры имеют разные типы: 0x,1x,3x,4x
2. контроллеры в принципе - один класс (тип)
3. каналы - тоже разные классы  (типы) : ModbusRTUMaster, ModbusRTUSlave,ModbusTCPMaster, ModbusTCPSlave

:)

Цитировать
Если это не учебное задание, то вполне можно под подобные задачи найти какое-нибудь удобное решение а не кодировать всё с 0 не зная языка. Улыбающийся

да! кое чего не знаю! :) но кодировать придется с 0 !


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: lit-uriy от Январь 20, 2009, 10:19
я для модбаса классы не городил, неудобно, все эти хахаряхи лучше в БД держать.


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Январь 20, 2009, 10:25
Цитировать
я для модбаса классы не городил, неудобно, все эти хахаряхи лучше в БД держать.

идея такая:

1. в БД будет храниться конфигурация модуля, т.е каналов - контроллеров - регистров...
2. при инициализации модуля - он читает свою конфу из БД и в соответствии с ней создает в памяти соосветствующие структуры данных... (чтобы постоянно не считывать конфу из БД и не "шуршать" винтом - а держать в оперативе)
3. тек значения опрошенных регистров пишет в БД только при их изменении (стобы не шуршать "винтом") и т.п


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: lenny от Октябрь 13, 2011, 21:40
UP!!!
А велосипед готов?
Не получается работать с эмулятором MBTCPSlave, коннект устанавливается, а регистры не поменять, может MBTCPSlave косой или я MBAP написать не могу(остальное вроде по спецификации). Как через сокет мастер работает?


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: kuzulis от Октябрь 13, 2011, 22:04
Цитировать
UP!!!
А велосипед готов?
Не получается работать с эмулятором MBTCPSlave, коннект устанавливается, а регистры не поменять, может MBTCPSlave косой или я MBAP написать не могу(остальное вроде по спецификации). Как через сокет мастер работает?
Не, не готов. Я даж скромную библиотечку для последовательного порта еще не осилил, а уж было замахнулся на что-то большее :)

Для эмуляции - есть хорошие утилитки (под винду) : Modsim32 и Modscan32, но их нада крякать :)


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: lenny от Октябрь 13, 2011, 23:32
Вот к сожалению все их надо крякать.


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: lenny от Октябрь 14, 2011, 11:10
Разобрался. Зачем они за эти программки деньги просят.


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: lenny от Октябрь 16, 2011, 14:35
А что такое input discretes в modbus?


Название: Re: Как создать класс с "меняющейся начинкой" ?
Отправлено: Akon от Октябрь 18, 2011, 17:44
Если в рантайм, то по механизму типа QVariant; иначе шаблон класса. Преимущества первого варианта - простота (в смысле, нет шаблонов), сорцы закрыты; второго - более "тонкий" (оптимальный) код, но сорцы открыты. Собственно, если конфигурация системы может меняться в рантайме (там один регистр заменить на другой и т.п.), то только первый вариант.