Russian Qt Forum

Программирование => С/C++ => Тема начата: Андрей80 от Март 14, 2009, 17:15



Название: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Андрей80 от Март 14, 2009, 17:15
Здравствуйте. Помогите пожалуйста, разобратся с switch! (С++, QT)
Так получилось, что почти всегда пользовался if ... else if в своих программах =). Решил наконец избавиться от этой вредной привычки. Но увы...
Буду благодарен если кто ткнёт носом в ошибку
Код:
QString param = descriptors[descriptor];
QStringList array = param.split(";");
SqlQuery squery;
query.exec(QString(array[0]));
int j = 2;
QString var = array[1];
switch (array[1])
{
case "special" :
while (j < array.size())
{
QStringList subarr = array[j].split("=");
text += subarr[0]  + " " + squery[subarr[1]] + ", ";
j++;
}
break;

case "day" :
{text = squery[array[2]];
QStringList subarr = text.split(":");
text  = subarr[0];}
break;

case "monthNum" :
{text = squery[array[2]];
QStringList subarr = text.split(":");
text  = subarr[1];}
break;

case "yearLast2" :
{text = squery[array[2]];
QStringList subarr = text.split(":");
text  = subarr[2];
text = text.remove(0, 2);}
break;

case "art" :
text = QString :: number(IT + 1); // IT - порядковый номер записи тт Накладной
break;

default:
while (j < array.size())
{
text += array[1] + squery[array[j]];
j++;
}
}

ошибка компилятора (компилирую в QDevelop + MinGW):
error: switch quantity not an integer

PS. При использовании if else if  работает на ура


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: BRE от Март 14, 2009, 17:18
В switch нельзя использовать строки (о чем он тебе в ошибке и говорит). Воспользуйся enum.
Код
C++ (Qt)
enum FieldType { specila, day, monthNum, yearLst, ..... };
 
FieldType fld = array[ 1 ];
switch( fld )
{
   case special:
       ....
   case day:
       ....
}
 


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Андрей80 от Март 14, 2009, 17:26
Спасибо!


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Андрей80 от Март 14, 2009, 17:42
Можно ещё вопрос не по теме... Почему у вас в ответе ситаксис с подсветкой, а у меня нет
Код:
int x = 0;
switch (x)

case 0:
 x++;
break;



Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Khs от Март 14, 2009, 17:51
Код
C++ (Qt)
int x = 0;
switch (x)
 
case 0:
x++;
break;

Выбери стиль в комбике, по стандарту там GeSHi вроде...


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: inst от Апрель 12, 2009, 20:41
Интереса ради хочу задать такой вопрос. В стандартном примере Calculator на Qt в файле calculator.cpp есть функция unaryOperatorClicked().

В ней используется условный переход по if-else if. А вот скажите, возможно ли это как-то переделать, чтоб использовать switch? Проблема та же, что и в первом посте. Какие возможны пути решения данной задачки?


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Rcus от Апрель 12, 2009, 21:02
У меня была схожая проблема: при реализации сетевого протокола надо обрабатывать каждый управляющий код отдельно, поэтому в обычном варианте получается большой switch. Здесь можно попробовать использовать табличное отображение в моем случае код выглядел так:
объявление приватного класса и заполнение таблицы методов:
Код
C++ (Qt)
class MServerConnectionPrivate
{
public:
   MServerConnectionPrivate(MServerConnection *value);
   MServer *server;
   quint32 clientId;
   bool sendGreeting();
   bool processPacket(MPacket &packet);
private:
   bool processIdChange(MPacket &packet);
   bool processServerMessage(MPacket &packet);
   bool processServerStatus(MPacket &packet);
   bool processServerIdent(MPacket &packet);
   bool processServerList(MPacket &packet);
   bool processSearchResult(MPacket &packet);
   bool processCallbackRequested(MPacket &packet);
   bool processCallbackFail(MPacket &packet);
   bool processReject(MPacket &packet);
   bool processFoundSources(MPacket &packet);
   bool processFoundSourcesObfuscated(MPacket &packet);
   typedef bool (MServerConnectionPrivate::*ProcessMethodPtr)(MPacket &packet);
   typedef QHash<quint8, ProcessMethodPtr> ProcessMethodsTable;
   ProcessMethodsTable table;
   MServerConnection *q;
};
#ifdef METHOD_TABLE_FILL
#error conflict in macro declaration
#endif
#define METHOD_TABLE_FILL(_Opcode_) \
   table[Opcode::_Opcode_] = &MServerConnectionPrivate::process##_Opcode_
MServerConnectionPrivate::MServerConnectionPrivate(MServerConnection *value) : q(value), clientId(0)
{
   METHOD_TABLE_FILL(IdChange);
   METHOD_TABLE_FILL(ServerStatus);
   METHOD_TABLE_FILL(ServerMessage);
   METHOD_TABLE_FILL(ServerIdent);
   METHOD_TABLE_FILL(ServerList);
   METHOD_TABLE_FILL(SearchResult);
   METHOD_TABLE_FILL(CallbackRequested);
   METHOD_TABLE_FILL(CallbackFail);
   METHOD_TABLE_FILL(Reject);
   METHOD_TABLE_FILL(FoundSources);
   METHOD_TABLE_FILL(FoundSourcesObfuscated);
}
#undef METHOD_TABLE_FILL
применение:
Код
C++ (Qt)
bool MServerConnectionPrivate::processPacket(MPacket &packet)
{
   ProcessMethodPtr method = table[packet.opcode()];
   if (!method) {
       qFatal("Method not found for opcode = %d", packet.opcode());//TODO:remove after implementing all
       return false;
   }
   qDebug("Found method to process packet, opcode = %d", packet.opcode());
   return (this->*method)(packet);
}

Нужно только определить qHash для типа по которому строится отображение. Хотя есть сомнение, возможно есть решение попроще.


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Khs от Апрель 12, 2009, 21:23
А записать нужные строки в QStringList иль QMap, и делать свитч по индексам (ну или в этой области что-то) это не есть гуд?

... чето подумал, не..лучше так не делать  ;)


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Danila_Bagrofff от Апрель 13, 2009, 14:42
всплыла трабла....

в общем свитч нормально работал по enum'ам.
Но теперь значения забиты в конф-файл, и следовательно стали переменны.
Кроме как if... else... нельзя никак заменить систему?
Код:
switch(iType)
{
     case abonent:
     //my code
    break;

    case phone:
    //my code
    break;

    case default:
   //my code
    //break
}

Раньше abonent и phone были enom'ом, а теперь int'ы. Всё, теперь нельзя никак применять такую схему?


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: spirit от Апрель 13, 2009, 16:20
почему нельзя? приведи iType к своему перечислению и юзай свич на здоровье.
хотя и так работать должно.


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Danila_Bagrofff от Апрель 14, 2009, 07:02
почему нельзя? приведи iType к своему перечислению и юзай свич на здоровье.
хотя и так работать должно.

Код:
int k = 0;
int iType;

switch(iType)
{
      case k:
           break;
}

Цитировать
C:/drag/dialog.cpp:280: error: `rs' cannot appear in a constant-expression

как это привести int к enum'у? 0_o


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: spirit от Апрель 14, 2009, 07:48
ну во-первых ругань идет на rs, во-вторых приводится просто
Код
C++ (Qt)
...
enum MyEnum { One = 1, Two, Three };
...
int iType = 3;
MyEnum t = MyEnum(iType);
 
switch (t) {
case One: {...}
           break;
case Two: {...}
           break;
case Three: {...}
           break;
default: {...}
           break;
};
 
покажи лучше код.


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Danila_Bagrofff от Апрель 14, 2009, 07:58
ЭЭ... rs это и есть k:

чуть забыл подправить код =)
Код:
int k = 0;
int iType;

switch(iType)
{
      case k:
           break;
}

Вот значения k и должны загружаться из конф-файла, а не браться из enuma. В инструкции case нужно вписывать константу. А у нас значение, вписываемое по ходу программы.


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: spirit от Апрель 14, 2009, 08:04
ну все верно компиль ругается, тогда.
в кейсах должны быть константные значения.
читай про switch (http://www.cyberguru.ru/programming/cpp/cpp-velvet-way-page61.html).


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Danila_Bagrofff от Апрель 14, 2009, 08:17
так я знаю =)

просто, думал, мож можно как-то обмануть. Просто кейсы удобнее, нежели if else =)


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: spirit от Апрель 14, 2009, 08:19
ну в данном случае ифы нужно юзать.


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Tonal от Апрель 14, 2009, 10:27
Интересно, а вопрошающие книжки по языку читать пробовали? :)


Название: Re: Помогите пожалуйста, разобратся с switch! (С++, QT)
Отправлено: Danila_Bagrofff от Апрель 14, 2009, 16:07
читали, и даже знаем, но просто проблему с "умными" идеями начальства все делать через кейсы никак им не объяснить, что нельзя. Но они хотят - и все.

=)