Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ С\С++ _ Обработка собственных исключений

Автор: legat 17.5.2011, 12:59

Суть проблемы:
Пытаюсь подключиться к SQLite БД в конструкторе класса DataWork. Пытаюсь в БД создать таблицу. Если таблица уже создана, то должно отработать исключение.

Раскрывающийся текст
int main( ) {
    DataWork db;
    try {
    } catch ( DataWork::Error e ) {
        std::cout << "catch error: " << e.errorStr << std::endl;
        return -1;
    }
    std::cout << "end of program" << std::endl;
    return 0;
}

const std::string CREATE_USERS_TABLE = "Create table users( id integer primary key autoincrement, login varchar(20), serverName varchar(20), password varchar(20) );";
DataWork::DataWork( ) {
    if ( sqlite3_open( DBNAME.c_str( ), &m_db ) != SQLITE_OK ) {
    char *errorMsg = ( char * ) sqlite3_errmsg( m_db );
        throw Error( errorMsg );
    }
    executeSQL( CREATE_USERS_TABLE );
}
DataWork::~DataWork( ) {
    sqlite3_close( m_db );
}
void DataWork::executeSQL( const std::string &sql, int ( *callback )( void *, int, char **, char ** ) ) {
    char *errorMsg;
    if ( sqlite3_exec( m_db, sql.c_str( ), callback, NULL, &errorMsg ) != SQLITE_OK ) {
        throw Error( errorMsg );
    }
}

class DataWork {
public:
    // структура ошибки
    struct Error {
        const char *errorStr;
        Error( const char *str ) : errorStr( str ) { }
    };
    DataWork( );
    ~DataWork( );
private:
    void executeSQL( const std::string &sql,
        int ( *callback )( void *, int, char **, char ** ) = NULL );
    
private:
    sqlite3 *m_db;
};


В теле функции ExecuteSQL выводится сообщение об ошибке (простая проверка, что сообщение вообще что-то содержит):
error happend!: table users already exists.
Так и должно быть.
Затем должно отработать моё исключение, но вместо этого выводится terminate called after throwing an instance of 'DataWork::Error' Аварийный останов. Программирую на клоне Debian.
Как сделать так, чтобы обработалось моё исключение и программа продолжила свою работу, т.е. вывела тестовое сообщение 'end of program'.

Автор: Rocky 17.5.2011, 14:34

Наверное не

    DataWork db;
    try {

а
  try {
DataWork db;

Автор: Litkevich Yuriy 19.5.2011, 7:04

Rocky, угу, так и выглядит оператор try-catch

Автор: Rocky 19.5.2011, 9:57

Да я в курсе)))) Это сарказм )))

legat, вообще не очень хорошо, если конструктор класса генерирует исключение.

Автор: Litkevich Yuriy 19.5.2011, 14:01

Цитата(Rocky @ 19.5.2011, 12:57) *
legat, вообще не очень хорошо, если конструктор класса генерирует исключение.
если исключения и использовать, то лучше в конструкторе.

Автор: Rocky 20.5.2011, 20:50

Цитата(Litkevich Yuriy @ 19.5.2011, 15:01) *
Цитата(Rocky @ 19.5.2011, 12:57) *
legat, вообще не очень хорошо, если конструктор класса генерирует исключение.
если исключения и использовать, то лучше в конструкторе.

Извини, не соглашусь. Погугли на тему "с++ исключение в конструкторе". Или есть такая книга Саттера "Решение сложных задач на С++". Я бы не стал говорить что лучше именно в конструкторе. Можно, но с головой. Это же относится и ко всему коду. В смысле если везде лепить блоки try/catch бездумно. Это вообще довольно сложная тема, и даже многие гуру до конца не понимают как это все работает.

Автор: Iron Bug 20.5.2011, 22:08

по-моему, использование исключения в конструкторе - нормальная практика. ошибки и утечки тут могут быть только из-за невнимательности программиста.
собственно, конструктор вообще не может вернуть ничего, кроме исключения, в случае ошибки. так что это нормально.

Автор: PAFOS 6.6.2011, 16:52

обработка исключений вообще платформозависимая тема (в плане реализации на нативном коде)
Но по сути она куда более сложна чем возврат кодов состояния.


Цитата
конструктор вообще не может вернуть ничего, кроме исключения, в случае ошибки. так что это нормально.


Можно возвращать значения по указателям и ссылкам, например.

Что я хотел сказать - исключения более ресурсоемкие по сравнению с возвращением кодов состояния. Лично я использую их в тех местах, где надо сделать что-то вроде транзакции. Так они более эффективны.

Автор: Iron Bug 6.6.2011, 23:10

Цитата(PAFOS @ 6.6.2011, 19:52) *
Что я хотел сказать - исключения более ресурсоемкие по сравнению с возвращением кодов состояния.

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

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)