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

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

Страниц: 1 ... 3 4 [5] 6 7   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Обработка ошибок без исключений и с помощью исключений  (Прочитано 50606 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #60 : Март 27, 2014, 13:16 »

Почему же их не использовать для обработки ошибок? Хотя бы на примере чтения из файла.
Использовать, и для чтения из файла - часто. Только Вы их неправильно используете, о чем я в этой теме уже говорил дважды - и даже рядом тему создал.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #61 : Март 27, 2014, 13:30 »

Почему же их не использовать для обработки ошибок?
Зачем вы спрашиваете чье то мнение? У вас сейчас пока еще есть возможность изучать и исследовать все, на что падает ваш взгляд. Воспользуйтесь этим. Скоро вас загонят в корпоративные рамки, где скажут использовать это и это, а это не использовать, а с этим делать так и никак иначе. Улыбающийся
В эти свободные времена, вам нужно постараться максимально расширить ваш технических кругозор. В дальнейшем, вы сможете сразу определять, в какие стороны можно посмотреть, что бы решить задачу.
Не слушайте никого: вам говорят так не делать - сделайте так, почувствуйте проблему или поймите что ее там нет и все это предрассудки.
Пробуйте, творите, выкладывайте здесь, будем обсуждать. Улыбающийся
Записан
8Observer8
Гость
« Ответ #62 : Март 27, 2014, 13:47 »

Спасибо огромное! Согласен! Отлично сказано, что надо сделать и самому почувствовать проблему или её отсутствие Улыбающийся
« Последнее редактирование: Март 27, 2014, 13:49 от 8Observer8 » Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #63 : Март 27, 2014, 13:59 »

Как это ни разу? А я же заменил showError() с помощью своих классов исключений Улыбающийся
А где на это можно посмотреть?
Записан
8Observer8
Гость
« Ответ #64 : Март 27, 2014, 14:07 »

Как это ни разу? А я же заменил showError() с помощью своих классов исключений Улыбающийся
А где на это можно посмотреть?

Приведу сразу все примеры:

Пример без исключений:
Код
C++ (Qt)
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <iostream>
 
//! Error codes
enum ErrorType {
   //! None errors
   errNone = 0,
 
   //! Error of the opening of a file
   errFileOpen = -1000,
 
   //! Error of the writing of a file
   errFileWrite = -1001,
 
   //! Wrong data
   errDataBad = -5000
};
 
ErrorType readData( const QString &fileName, QString &data );
ErrorType writeResult( const QString &fileName, QString &data );
void showData( const QString &data );
ErrorType showError( const QString &fileName, ErrorType errorCode );
 
/*!
* Working with a text file
*/

int main( int argc, char *argv[] ) {
   QCoreApplication a( argc, argv );
 
   QString data;
   ErrorType errorCode = ErrorType::errNone;
 
   // Read data from a file
   QString iFileName = QString( "input.txt" );
   errorCode = readData( iFileName, data );
   if ( errorCode != ErrorType::errNone ) {
       return showError( iFileName, errorCode );
   }
 
   // Show data on the screen
   showData( data );
 
   // Data processing
   data += QString( ", World" );
 
   // Write data to a file
   QString oFileName = QString( "output.txt" );
   writeResult( oFileName, data );
   if ( errorCode != ErrorType::errNone ) {
       return showError( oFileName, errorCode );
   }
 
   return a.exec( );
}
 
/*!
* Read data from the file
* \param fileName File name
* \param data data
* \return Error code
*/

ErrorType readData( const QString &fileName, QString &data ) {
   QFile file( fileName );
   if ( !file.open( QIODevice::ReadOnly ) ) {
       return ErrorType::errFileOpen;
   }
 
   data = file.readAll( );
 
   file.close( );
   return ErrorType::errNone;
}
 
/*!
* Write data to the file
* \param fileName Fleile name
* \param data Data
* \return Error code
*/

ErrorType writeResult( const QString &fileName, QString &data ) {
   QFile file( fileName );
 
   if ( !file.open( QIODevice::WriteOnly ) ) {
       return ErrorType::errFileOpen;
   }
 
   QTextStream stream( &file );
   stream << data;
   file.close( );
 
   if ( stream.status( ) != QTextStream::Ok ) {
       return ErrorType::errFileWrite;
   }
 
   return ErrorType::errNone;
}
 
/*!
* Show data on the screen
* \param data Data
*/

void showData( const QString &data ) {
   std::cout << data.toStdString( ) << std::endl;
}
 
/*!
* Write the error code to the file
* \param fileName File name
* \param errorCode Error code
* \return Error code
*/

ErrorType showError( const QString &fileName, ErrorType errorCode ) {
   switch ( errorCode ) {
       case ErrorType::errFileOpen:
           std::cerr << "Error: cannot open the file " << fileName.toStdString( ) << std::endl;
           break;
       case ErrorType::errFileWrite:
           std::cerr << "Error: cannot write to the file " << fileName.toStdString( ) << std::endl;
           break;
       case ErrorType::errDataBad:
           std::cerr << "Error: incorrect data in the file " << fileName.toStdString( ) << std::endl;
           break;
       default:
           std::cerr << "Error code: " << errorCode << "; file name: " << fileName.toStdString( ) << std::endl;
           break;
   }
 
   return errorCode;
}
 

Пример с исключениями

Код
C++ (Qt)
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QVector>
#include <iostream>
#include <exception>
 
void readData( const QString &fileName, QVector<int> &arr )
throw (std::invalid_argument, std::runtime_error);
 
void writeResult( const QString &fileName, QVector<int> &arr )
throw (std::invalid_argument, std::runtime_error);
 
void showData( const QVector<int> &arr );
 
/*!
* Working with a text file
*/

int main( int argc, char *argv[] ) {
   QCoreApplication a( argc, argv );
 
   // Read data from a file
   QString iFileName = QString( "input.txt" );
   QVector<int> arr;
   try {
       readData( iFileName, arr );
   } catch ( const std::exception &e ) {
       std::cerr << e.what( ) << std::endl;
       return 1;
   }
 
   // Show data on the screen
   showData( arr );
 
   // Data processing
   arr.push_back( 100 );
 
   // Write data to a file
   QString oFileName = QString( "output.txt" );
   try {
       writeResult( oFileName, arr );
   } catch ( const std::exception &e ) {
       std::cerr << e.what( ) << std::endl;
       return 1;
   }
 
   return a.exec( );
}
 
/*!
* Read data from the file
* \param fileName File name
* \param data data
*/

void readData( const QString &fileName, QVector<int> &dest )
throw (std::invalid_argument, std::runtime_error) {
   QFile file( fileName );
 
   if ( !file.open( QIODevice::ReadOnly ) ) {
       std::string error = "Unable to open the file " + fileName.toStdString( );
       throw std::invalid_argument( error );
   }
 
   QTextStream stream( &file );
 
   QString input;
   do {
       stream >> input;
       bool ok;
       int value = input.toInt( &ok );
       if ( (ok) && (stream.status( ) == QTextStream::Ok) ) {
           dest.push_back( value );
       } else if ( !stream.atEnd( ) ) {
           std::string error = "Unable to read file " + fileName.toStdString( );
           throw std::runtime_error( error );
       }
   } while ( !stream.atEnd( ) );
}
 
/*!
* Write data to the file
* \param fileName Fleile name
* \param data Data
* \return Error code
*/

void writeResult( const QString &fileName, QVector<int> &arr )
throw (std::invalid_argument, std::runtime_error) {
   QFile file( fileName );
 
   if ( !file.open( QIODevice::WriteOnly ) ) {
       std::string error = "Unable to open the file " + fileName.toStdString( );
       throw std::invalid_argument( error );
   }
 
   QTextStream stream( &file );
   for ( int i = 0; i < arr.size( ); ++i ) {
       stream << arr[i];
       if ( i != (arr.size( ) - 1) ) {
           stream << " ";
       } else {
           stream << endl;
       }
   }
   file.close( );
 
   if ( stream.status( ) != QTextStream::Ok ) {
       std::string error = "Unable to write to the file " + fileName.toStdString( );
       throw std::runtime_error( error );
   }
}
 
/*!
* Show data on the screen
* \param data Data
*/

void showData( const QVector<int> &arr ) {
   for ( int i = 0; i < arr.size( ); ++i ) {
       std::cout << QString::number( arr[i] ).toStdString( ) << std::endl;
   }
}
 

Пример со своими классами исключений
text_file.pro
Код
C++ (Qt)
#-------------------------------------------------
#
# Project created by QtCreator 2014-03-16T19:25:22
#
#-------------------------------------------------
 
QT       += core
 
QT       -= gui
 
QMAKE_CXXFLAGS += -std=c++11
 
TARGET = text_file
CONFIG   += console
CONFIG   -= app_bundle
 
TEMPLATE = app
 
 
SOURCES += main.cpp
 
HEADERS += \
   FileError.h \
   FileOpenError.h \
   FileReadError.h \
   FileWriteError.h
 

FileError.h
Код
C++ (Qt)
#ifndef FILEERROR_H
#define FILEERROR_H
 
#include <QString>
#include <exception>
#include <string>
 
class FileError : public std::runtime_error {
public:
 
   FileError( const QString &fileIn ) : std::runtime_error( "" ), mFile( fileIn ) {
   }
 
   virtual const char* what( ) const noexcept {
       return mMsg.c_str( );
   }
 
   QString getFileName( ) const {
       return mFile;
   }
 
protected:
   QString mFile;
   std::string mMsg;
};
 
#endif // FILEERROR_H
 

FileOpenError.h
Код
C++ (Qt)
#ifndef FILEOPENERROR_H
#define FILEOPENERROR_H
 
#include <QString>
#include "FileError.h"
 
class FileOpenError : public FileError {
public:
 
   FileOpenError( const QString &fileNameIn ) : FileError( fileNameIn ) {
       //mMsg = QString("Unable to open ") + fileNameIn;
       mMsg = "Unable to open " + fileNameIn.toStdString( );
   }
};
 
#endif // FILEOPENERROR_H
 

FileReadError.h
Код
C++ (Qt)
#ifndef FILEREADERROR_H
#define FILEREADERROR_H
 
#include "FileError.h"
#include <QString>
#include <QTextStream>
#include <sstream>
 
class FileReadError : public FileError {
public:
 
   FileReadError( const QString &fileNameIn, int lineNumIn ) :
   FileError( fileNameIn ), mLineNum( lineNumIn ) {
       //        QTextStream stream(stdout);
 
       //        //stream << QString("Error reading ") << fileNameIn << QString(" at line ") << lineNumIn;
       //        mMsg = QString("Error reading %1 at line %2").arg(fileNameIn).arg(lineNumIn);
       //        stream >> mMsg;
       std::ostringstream ostr;
 
       ostr << "Error reading " << fileNameIn.toStdString( ) << " at line " << lineNumIn;
       mMsg = ostr.str( );
   }
 
   int getLineNum( ) const {
       return mLineNum;
   }
 
protected:
   int mLineNum;
};
 
#endif // FILEREADERROR_H
 

FileWriteError.h
Код
C++ (Qt)
#ifndef FILEWRITEERROR_H
#define FILEWRITEERROR_H
 
#include <QString>
#include "FileError.h"
 
class FileWriteError : public FileError {
public:
 
   FileWriteError( const QString &fileNameIn ) : FileError( fileNameIn ) {
       //mMsg = QString( "Unable to write " ) + fileNameIn;
       mMsg = "Unable to write " + fileNameIn.toStdString( );
   }
};
 
#endif // FILEWRITEERROR_H
 

main.cpp
Код
C++ (Qt)
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QVector>
#include <iostream>
#include "FileOpenError.h"
#include "FileReadError.h"
#include "FileWriteError.h"
 
void readData( const QString &fileName, QVector<int> &arr )
throw (FileOpenError, FileReadError);
 
void writeResult( const QString &fileName, QVector<int> &arr )
throw (FileOpenError, FileWriteError);
 
void showData( const QVector<int> &arr );
 
/*!
* Working with a text file
*/

int main( int argc, char *argv[] ) {
   QCoreApplication a( argc, argv );
 
   // Read data from a file
   QString iFileName = QString( "input.txt" );
   QVector<int> arr;
   try {
       readData( iFileName, arr );
   } catch ( const FileError &e ) {
       std::cerr << e.what( ) << std::endl;
       return 1;
   }
 
   // Show data on the screen
   showData( arr );
 
   // Data processing
   arr.push_back( 100 );
 
   // Write data to a file
   QString oFileName = QString( "output.txt" );
   try {
       writeResult( oFileName, arr );
   } catch ( const FileError &e ) {
       std::cerr << e.what( ) << std::endl;
       return 1;
   }
 
   return a.exec( );
}
 
/*!
* Read data from the file
* \param fileName File name
* \param data data
*/

void readData( const QString &fileName, QVector<int> &dest )
throw (FileOpenError, FileReadError) {
   QFile file( fileName );
 
   if ( !file.open( QIODevice::ReadOnly ) ) {
       throw FileOpenError( fileName );
   }
 
   QTextStream stream( &file );
 
   QString input;
   int lineNumber = 0;
   do {
       lineNumber++;
       stream >> input;
       bool ok;
       int value = input.toInt( &ok );
       if ( (ok) && (stream.status( ) == QTextStream::Ok) ) {
           dest.push_back( value );
       } else if ( !stream.atEnd( ) ) {
           throw FileReadError( fileName, lineNumber );
       }
   } while ( !stream.atEnd( ) );
}
 
/*!
* Write data to the file
* \param fileName Fleile name
* \param data Data
* \return Error code
*/

void writeResult( const QString &fileName, QVector<int> &arr )
throw (FileOpenError, FileWriteError) {
   QFile file( fileName );
 
   if ( !file.open( QIODevice::WriteOnly ) ) {
       throw FileOpenError( fileName );
   }
 
   QTextStream stream( &file );
   for ( int i = 0; i < arr.size( ); ++i ) {
       stream << arr[i];
       if ( i != (arr.size( ) - 1) ) {
           stream << " ";
       } else {
           stream << endl;
       }
   }
   file.close( );
 
   if ( stream.status( ) != QTextStream::Ok ) {
       throw FileWriteError( fileName );
   }
}
 
/*!
* Show data on the screen
* \param data Data
*/

void showData( const QVector<int> &arr ) {
   for ( int i = 0; i < arr.size( ); ++i ) {
       std::cout << QString::number( arr[i] ).toStdString( ) << std::endl;
   }
}
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #65 : Март 27, 2014, 14:15 »

Код
C++ (Qt)
   do {
       stream >> input;
       bool ok;
       int value = input.toInt( &ok );
       if ( (ok) && (stream.status( ) == QTextStream::Ok) ) {
           dest.push_back( value );
       } else if ( !stream.atEnd( ) ) {
           std::string error = "Unable to read file " + fileName.toStdString( );
           throw std::runtime_error( error );
       }
   } while ( !stream.atEnd( ) );
}
 
Такое использование исключений не дает выгод, "зато" засоряет код капитально. A вот пример силы исключений
Код
C++ (Qt)
stream >> dest;  // вместо всей бадяги выше
 
Конечно это надо подготовить (возможно классами) - но оно того стоит
Записан
8Observer8
Гость
« Ответ #66 : Март 27, 2014, 14:23 »

Вы не могли бы подробнее написать. Набросками. Как этот код в классы убрать?
Записан
Bepec
Гость
« Ответ #67 : Март 27, 2014, 14:26 »

Можно проще написать - так как в Qt разработчики отказались от исключений, то для их внедрения вам придётся переписать большую часть Qt. Веселый А это бессмысленно.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #68 : Март 27, 2014, 14:27 »

Вот функция main из одного моего небольшого проекта
Код
C++ (Qt)
using namespace xxx;
 
int main( int argc, char *argv[] )
{
       try
       {
               Application app;
               app.parseCommandLine( argc, argv );
               app.isRunning();
               app.daemonize();
               app.checkCfgFile();
               app.exec();
       }
       catch( const std::exception &x )
       {
               Log( "%s", x.what() );
               return 1;
       }
       catch( ... )        // Специальная ветка для Вереса, что бы ничего не падало тихо. :)
       {
               Log( "Shit! Unknow exception. :)" );
               return -1;
       }
 
       return 0;
}
 

Если где-то внутри я могу повлиять на работу программы при возникновении исключения, то там имеем локальный блок try-catch для интересующих в данный момент исключений.
Выпали в main, значит все что мы можем, это сохранить в лог всю доступную информацию и выйти.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #69 : Март 27, 2014, 14:30 »

Можно проще написать - так как в Qt разработчики отказались от исключений, то для их внедрения вам придётся переписать большую часть Qt. Веселый А это бессмысленно.
Да, очень жаль, что когда Qt начинали разрабатывать не было ни одного компилятора, умеющего их нормально. Вот теперь пожинаем. Грустный
Записан
Bepec
Гость
« Ответ #70 : Март 27, 2014, 14:34 »

to Old:
У вас всё сводится к логированию и выходу из программы. Я же имел в виду восстановле ние работоспособности программы Улыбающийся  Но фу фу - не буду спорить. В качестве "падает тихо" пойдёт Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #71 : Март 27, 2014, 14:37 »

Вы не могли бы подробнее написать. Набросками. Как этот код в классы убрать?
Смысл в том, что бы было возможно писать так:
Код
C++ (Qt)
try
{
   Stream stream( ... );
 
   stream >> id;
   stream >> data1;
   stream >> data2;
}
catch( const ErrorTypeOne &ex )
{
}
catch( const ErrorTypeTwo &ex )
{
}
 
В этом случае, логика чтения/записи не захламляется проверками.
Записан
8Observer8
Гость
« Ответ #72 : Март 27, 2014, 14:42 »

Можно проще написать - так как в Qt разработчики отказались от исключений, то для их внедрения вам придётся переписать большую часть Qt. Веселый А это бессмысленно.

Зато разработчики STD и Boost активно их используют. Надо отлавливать все исключения, как и проверять коды функций на случай если они отработали неверно.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #73 : Март 27, 2014, 14:43 »

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

Или вам нужен пример, в каких случаях программа может восстановиться при исключении? Так их есть у меня. Улыбающийся
« Последнее редактирование: Март 27, 2014, 14:45 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #74 : Март 27, 2014, 14:56 »

Вы не могли бы подробнее написать. Набросками. Как этот код в классы убрать?
Для чтения int используйте http://www.prog.org.ru/index.php?topic=26733.msg192575#msg192575 Только замените QDataStream на QTextStream. Чтение вектора допишете (наск помню его в QTextStream нет)
Записан
Страниц: 1 ... 3 4 [5] 6 7   Вверх
  Печать  
 
Перейти в:  


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