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

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

Страниц: 1 ... 8 9 [10] 11 12   Вниз
  Печать  
Автор Тема: Тренировка навыков быстрого программирования  (Прочитано 80846 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Код
C++ (Qt)
int showError(int errorCode, const std::string& fileName) {
   switch (errorCode) {
   case ErrorType::errCannotOpenFile:
       std::cerr << "Error: cannot open the file " << fileName.c_str() << std::endl;
       break;
 
c_str излишне, cerr умеет выводить std::string. Также откуда Вы возьмете fileName если ошибка не связана с файлом? Гибче так
Код
C++ (Qt)
int showError(int errorCode, const std::string& fileName = std::string());
 
Или так
Код
C++ (Qt)
int showError(int errorCode, const char * fileName = 0);
int showError(int errorCode, const char * msg1 = 0, const char * msg2 = 0);
 
Здесь придется чуть повозиться (просто так fileName не напечатать), но возможностей больше. И, строго говоря, "Error: cannot open the file " не есть хорошо, строки-константы должны грузиться из ресурсов
Записан
8Observer8
Гость
« Ответ #136 : Март 18, 2014, 06:05 »

Igors, огромное спасибо! Возьму на вооружение Улыбающийся

Я так и не понял, зачем функция showError() возвращает код ошибки, который она и принимает? Это может иметь смысл?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Я так и не понял, зачем функция showError() возвращает код ошибки, который она и принимает? Это может иметь смысл?
Пример
Код
C++ (Qt)
if (!veс.size()) {
ShowError(errNoData, "not enough data");
return;
}
 
if (!veс.size())
return ShowError(errNoData, "not enough data");
 
Второй вариант симпатичнее
Записан
8Observer8
Гость
« Ответ #138 : Март 18, 2014, 09:18 »

Посмотрите, пожалуйста, на следующий код. Если у нас файл не открылся, а мы его закрываем в этом нет ничего страшного?

Код
C++ (Qt)
enum ErrorType {
   errCannotOpenFile,
   errCannotWriteToFile,
   errIncorrectData,
   errNo
};
 
// ...
 
int readData(const QString & fileName, QString & data) {
   QFile iFile(fileName);
 
   ErrorType errorType;
 
   if (!iFile.open(QIODevice::ReadOnly)) {
       errorType = ErrorType::errCannotOpenFile;
   } else {
       data = iFile.readAll();
       errorType ErrorType::errNo;
   }
 
   iFile.close();
   return errorType;
}
 
Записан
OKTA
Гость
« Ответ #139 : Март 18, 2014, 09:23 »

Почему бы сразу не сделать return в том месте, где возникать должна ошибка открытия?
Записан
Johnik
Крякер
****
Online Online

Сообщений: 339


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

а почему бы не сделать тогда так:
Код
C++ (Qt)
int readData(const QString & fileName, QString & data) {
   QFile iFile(fileName);
 
   ErrorType errorType;
 
   if (!iFile.open(QIODevice::ReadOnly)) {
       errorType = ErrorType::errCannotOpenFile;
   } else {
       data = iFile.readAll();
       errorType ErrorType::errNo;
       iFile.close();
   }
 
   return errorType;
}
 
Записан
8Observer8
Гость
« Ответ #141 : Март 18, 2014, 09:30 »

Да, вот этот вариант мне подходит. Люблю, когда один выход из функции Улыбающийся

Можно, конечно, как OKTA предложил:

Код
C++ (Qt)
int readData(const QString & fileName, QString & data) {
   QFile iFile(fileName);
 
   if (!iFile.open(QIODevice::ReadOnly)) {
       return ErrorType::errCannotOpenFile;
   } else {
       data = iFile.readAll();
       iFile.close();
       return ErrorType::errNo;
   }
}
 
Записан
OKTA
Гость
« Ответ #142 : Март 18, 2014, 09:37 »

Возвращать значение сразу удобно, когда после ошибки еще куча кода, которому не имеет смысла работать в случае ошибки.
Разработчики винды, к примеру, знаю не гнушаются ставить перед последним return метку типа "cleanup:" и после нее проводить нужные операции завершения, если они нужны. А в местах, где может возникать ошибка, ставят макрос типа #define CHECK_STATUS(Status) if(!NT_SUCCESS(Status)) {goto cleanup;}
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

Разработчики винды
Ох далеко не лучший пример. Улыбающийся

Выход по goto может заметно сократить функцию в С, потому что очистка всех ресурсов будет происходить в одном месте.
В С++ это не нужно, потому что можно и нужно использовать RAII.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

1) Уберите close(), оно вообще не нужно, деструктор сам закроет

2)
Код
C++ (Qt)
       errorType = ErrorType::errCannotOpenFile;
 
А здесь переборщили. Вместо errorType лучше error или даже err, здесь "Type" только сбивает. Квалифицировать имя - ну можно, но необязательно, на мой вкус лучше так
Код
C++ (Qt)
enum {
   errNone     = 0,
   errFileOpen = -1000,
   errFileWrite = -1001,
 
   errDataBad = -5000,
   errDataNoFormat = -5001,
};
 
Префикс err достаточно выразителен сам по себе, не вижу с чем он заклинит. Может "err_" еще лучше. Код errNone обязательно ноль. А коды ошибок лучше распихать по группам.

3)
Люблю, когда один выход из функции Улыбающийся
Тогда не забывайте присваивать переменой ошибки начальное значение  Улыбающийся
Записан
8Observer8
Гость
« Ответ #145 : Март 18, 2014, 10:31 »

А что означает: errDataNoFormat?

Я вот так хочу писать:

Код
C++ (Qt)
/**
* Коды ошибок
*/

enum ErrorType {
   errNone = 0,            /**< Нет ошибок */
   errFileOpen = -1000,    /**< Ошибка отрытия файла */
   errFileWrite = -1001,   /**< Ошибка записи в файл */
 
   errDataBad = -5000      /**< Некорректные данные в файле */
};
 

А с помощью Doxywizard можно сгерерировать такую документацию для своего проекта, как в этом примере: http://qwt.sourceforge.net/class_qwt_plot.html

В документации для Goxygen вот так написано:
Код
C++ (Qt)
/**
*  A test class. A more elaborate class description.
*/

class Test{
public:    
   /**      
    * An enum.    
    * More detailed enum description.    
    */
   
   enum TEnum {          
       TVal1, /**< enum value TVal1. */            
       TVal2, /**< enum value TVal2. */            
       TVal3  /**< enum value TVal3. */          
   }        *enumPtr, /**< enum pointer. Details. */      
   enumVar;  /**< enum variable. Details. */            
   /**      
    * A constructor.      
    * A more elaborate description of the constructor.      
    */
     
   Test();      
   /**      
    * A destructor.      
    * A more elaborate description of the destructor.      
    */
   
   ~Test();          
   /**      
    * a normal member taking two arguments and returning an integer value.      
    * @param a an integer argument.      
    * @param s a constant character pointer.      
    * @see Test()      
    * @see ~Test()      
    * @see testMeToo()      
    * @see publicVar()      
    * @return The test results      
    */
     
   int testMe(int a,const char *s);            
   /**      
    * A pure virtual member.      
    * @see testMe()      
    * @param c1 the first argument.      
    * @param c2 the second argument.      
    */
     
   virtual void testMeToo(char c1,char c2) = 0;        
   /**        
    * a public variable.      
    * Details.      
    */
     
   int publicVar;            
   /**      
    * a function variable.      
    * Details.      
    */
     
   int (*handler)(int a,int b);
};
 
« Последнее редактирование: Март 18, 2014, 11:08 от 8Observer8 » Записан
8Observer8
Гость
« Ответ #146 : Март 18, 2014, 11:05 »

Я сейчас открыл исходники Qwt (qwt_plot.h). Там enum вот так оформляется:
Код
C++ (Qt)
public:
   //! \brief Axis index
   enum Axis
   {
       //! Y axis left of the canvas
       yLeft,
 
       //! Y axis right of the canvas
       yRight,
 
       //! X axis below the canvas
       xBottom,
 
       //! X axis above the canvas
       xTop,
 
       //! Number of axes
       axisCnt
   };
 

В документации это потом выглядит вот так:


Ну и пример из документации Doxygen нужно другой взять (предыдущий был Java style, а этот Qt style):

Цитировать
Here is an example of a documented piece of C++ code using the Qt style:

Код
C++ (Qt)
/*!  A more elaborate class description.*/
class Test {
public:
   //! An enum.    
 
   /*! More detailed enum description. */
   enum TEnum {
       TVal1, /*!< Enum value TVal1. */
       TVal2, /*!< Enum value TVal2. */
       TVal3 /*!< Enum value TVal3. */
   }
   //! Enum pointer.        
   /*! Details. */
   *enumPtr,
   //! Enum variable.        
   /*! Details. */
   enumVar;
 
   //! A constructor.    
   /*!      
     A more elaborate description of the constructor.    
    */

   Test();
   //! A destructor.    
   /*!      
     A more elaborate description of the destructor.    */

   ~Test();
 
   //! A normal member taking two arguments and returning an integer value.    
   /*!      
     \param a an integer argument.      
     \param s a constant character pointer.      
     \return The test results      
     \sa Test(), ~Test(), testMeToo() and publicVar()    
    */

   int testMe(int a, const char *s);
   //! A pure virtual member.    
   /*!      
     \sa testMe()      
     \param c1 the first argument.      
     \param c2 the second argument.    
    */

   virtual void testMeToo(char c1, char c2) = 0;
   //! A public variable.    
   /*!      
     Details.    
    */

   int publicVar;
 
   //! A function variable.    
   /*!      
     Details.    
    */

   int (*handler)(int a, int b);
};
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

В цитируемых Вами примерах enum'ы внутри классов. С каким классом можно связать напр errDataBad? Не видно с каким, ну и не нужно навязывать класс (или пр-во имен), слава богу это не жаба. В глобальных enum нет ничего плохого если они хорошо продуманы. Вообще не стремитесь "навернуть", часто (если не всегда) можно сделать проще, напр
Код
C++ (Qt)
typedef int TErrCode;
 
int DoSomething1( void );  // что оно вернет - хз
TErrCode DoSomething2( void );  // ага!
 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

В глобальных enum нет ничего плохого если они хорошо продуманы.
Плохого в них ничего и нет, но только неименованные не позволяют контролировать на этапе компиляции, то что позволяют именованные, а именно:
Код
C++ (Qt)
void showError( int err )
{
}
 
void showError( ErrorType err )
{
}
 
Вот в первом случае мне компилятор разрешит передать в качестве параметра любую фигню, в отличие от второго варианта.
« Последнее редактирование: Март 18, 2014, 12:07 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

Вот в первом случае мне компилятор разрешит передать в качестве параметра любую фигню, в отличие от второго варианта.
Часто это ничем особенным не грозит, напр в данном случае распечатается код неизвестной ошибки. А вот иметь всюду ErrorType:: все-таки отягощает текст. Впрочем, все это уже вкусовщина  Улыбающийся
Записан
Страниц: 1 ... 8 9 [10] 11 12   Вверх
  Печать  
 
Перейти в:  


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