Russian Qt Forum
Июнь 16, 2024, 20:18 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: QDataStream + exception  (Прочитано 17271 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Март 25, 2014, 20:38 »

Добрый день

Навеяно соседней темой. Желание иметь исключения при любой ошибке чтения/записи вполне естественно - бесконечные проверки быстро утомляют. Но QDataStream ничего не испускает. Как быть?

Спасибо
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #1 : Март 25, 2014, 21:05 »

QDataStream это форматировщик, который пишет средствами переданного QIODevice.
Если вы напишите наследника QIODevice, который будет посылать исключения, то все у вас получиться.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Март 26, 2014, 10:32 »

QDataStream это форматировщик, который пишет средствами переданного QIODevice.
Если вы напишите наследника QIODevice, который будет посылать исключения, то все у вас получиться.
То ясно но не привлекательно. QDataStream может читать напр из QFile или из QByteArray или еще из чего-то - и все эти классы надо перекрывать  Плачущий

На первый взгляд может показаться что все просто
Код
C++ (Qt)
struct MyDataStream : public QDataStream {
MyDataStream( QDataStream & strm ) : mStrm(strm) {}
 
template <class T>
MyDataStream & operator >> ( T & dst )
{
mStrm >> dst;
if (mStrm.status() != Ok)
throw "Error";
return *this;
}
 
QDataStream & mStrm;
};
 
Но это не так  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Март 26, 2014, 10:34 »

QDataStream может читать напр из QFile или из QByteArray или еще из чего-то - и все эти классы надо перекрывать  Плачущий
Нет. Достаточно перекрыть QFile. Вряд ли при чтении из QBuffer (а именно он используется для QByteArray) может произойти ошибка. Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #4 : Март 26, 2014, 10:38 »

На первый взгляд может показаться что все просто
Но это не так  Улыбающийся
Ба, да у вы и наследование от QDataStream, и еще в качестве параметра экземпляр передаете... Богатое решение. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Март 26, 2014, 10:42 »

Нет. Достаточно перекрыть QFile. Вряд ли при чтении из QBuffer (а именно он используется для QByteArray) может произойти ошибка. Улыбающийся
Пример: рассчитываем что прочитаем 5 чисел - а в файле (или QBuffer) только 2.  

Ба, да у вы и наследование от QDataStream, и еще в качестве параметра экземпляр передаете... Богатое решение. Улыбающийся
Вот только не совсем верное  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #6 : Март 26, 2014, 10:44 »

Вот только не совсем верное  Улыбающийся
Вы обращаете внимание на такую ерунду?  Строит глазки
Да нормально... сойдет...  Подмигивающий
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #7 : Март 26, 2014, 10:49 »

Пример: рассчитываем что прочитаем 5 чисел - а в файле (или QBuffer) только 2.  
Вот подумал: можно сделать этакое прокси-устройтсво, которое будет с работать с реальным объектом QIODevice, проверять ошибки и посылать исключения. Такой класс будет один и позволит работать с любыми устройствами.

Еще поправочка:
То ясно но не привлекательно. QDataStream может читать напр из QFile или из QByteArray или еще из чего-то - и все эти классы надо перекрывать  Плачущий
Я так понимаю, что для вас более привлекательное решение сделать много своих QDataStream, QTextStream, QXmlStream, QJsonStream...
« Последнее редактирование: Март 26, 2014, 10:54 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Март 26, 2014, 11:06 »

Вот подумал: можно сделать этакое прокси-устройтсво, которое будет с работать с реальным объектом QIODevice, проверять ошибки и посылать исключения. Такой класс будет один и позволит работать с любыми устройствами.
Прошу исполнить  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #9 : Март 26, 2014, 11:08 »

Прошу исполнить  Улыбающийся
Не-не-не, сами-сами. Улыбающийся
Записан
Akon
Гость
« Ответ #10 : Март 26, 2014, 18:05 »

Такое прокси-устройство называется "Декоратор". И в данном случае он не решит всех проблем:
QDataStream::QDataStream ( const QByteArray & a ) -
этот конструктор внутренне создает QBuffer, который вы не сможете декорировать.

Как вариант: сделать свою обертку над QDataStream (она даже не наследник). Функции обертки реализуются через соответствующие функции QDataStream с выбросом исключения при ошибке.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #11 : Март 26, 2014, 18:19 »

Такое прокси-устройство называется "Декоратор".
Я программировал на C++ задолго до того, как начали придумывать названия разным приемам, уж простите старика, я не фапаю на названия паттернов. Улыбающийся

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

Как вариант: сделать свою обертку над QDataStream (она даже не наследник). Функции обертки реализуются через соответствующие функции QDataStream с выбросом исключения при ошибке.
Вот от этого и хотим уйти. Потому что, тогда проще написать свой вариант stream'а с блекжеком и дамами. Улыбающийся
А в прокси-устройстве будет достаточно перекрыть пару методов для чтения/записи, проверять в них результат и бросать исключения.
Да и логически, это более правильно. Стримы всего лишь форматировщики, умеющие писать/читать в определенном формате, а для самих операций использующие возможности своего QIODevice.
К тому же не нужно будет писать свои обертки для QTextStream, QXmlStreamXXX, QJsonStream и т.д. Улыбающийся
« Последнее редактирование: Март 27, 2014, 08:43 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Март 26, 2014, 18:26 »

Такое прокси-устройство называется "Декоратор". И в данном случае он не решит всех проблем:
QDataStream::QDataStream ( const QByteArray & a ) -
этот конструктор внутренне создает QBuffer, который вы не сможете декорировать.
Совершенно верно, при попытке QDataStream::setDevice() он будет удален. Добавлю что это не единственная причина по которой декоратор здесь не проходит

Как вариант: сделать свою обертку над QDataStream (она даже не наследник). Функции обертки реализуются через соответствующие функции QDataStream с выбросом исключения при ошибке.
Ну там их всех точно не перестрелять, а многие просто могут быть просто недоступны. Так что это не выход.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #13 : Март 26, 2014, 18:35 »

Совершенно верно, при попытке QDataStream::setDevice() он будет удален.
Конечно, будет удален. Так же как и с конструктором, вы как пользователь стрима, можете передать указатель на обычное устройство и тогда не будете получать исключения или на специальное прокси устройство и сможете получать. Никаких логических ошибок здесь нет.

Добавлю что это не единственная причина по которой декоратор здесь не проходит
Так огласите пожалуйста весь список. Но что то мне подсказывает, что это все очередные выдумки. Улыбающийся

И да, декоратор для устройства здесь подходит очень хорошо. Одноразовое написание, простая реализация, весь ранее написанный код остается полностью работоспособным.
« Последнее редактирование: Март 26, 2014, 18:50 от Old » Записан
Akon
Гость
« Ответ #14 : Март 26, 2014, 20:20 »

Цитировать
И не надо. Если пользователь решил воспользоваться этим конструктором, то он не получит ожидаемые исключения.
Тут все просто: ходите получать исключения, используете нужное прокси-устройство, нет - не используете.
Это плохой подход. Представьте, я получаю в функцию в качестве параметра экземпляр QDataStream. Я не знаю, каким конструктором он был создан, поэтому как мне обрабатывать ошибки: ловить исключениия или проверять инфу об ошибках?

Цитировать
Ну там их всех точно не перестрелять, а многие просто могут быть просто недоступны. Так что это не выход.
Речь идет о пабликах, разумеется. И их не так много. Я в таких случаях поступаю так: реализую сначало то, что непосредственно нужно (возможно, это всего лишь пара функций). В следующем проекте что-то дописывается и так далее.
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.169 секунд. Запросов: 22.