Исключения как механизм обработки ошибок Варианты обработки ошибок без исключений: 1.Умолчание ошибки int atoi ( const char * str ); const char * strVal. презентация

Содержание

Исключения как механизм обработки ошибок Варианты обработки ошибок без исключений: Умолчание ошибки int atoi ( const char * str ); const char * strVal = “abc”;

Слайд 2Исключения как механизм обработки ошибок
Варианты обработки ошибок без исключений:
Умолчание ошибки

int atoi ( const char * str );

const char * strVal = “abc”;

const int val = atoi(strVal); // результат функции 0
2. Возвратить результат операции
bool strToInt(const char * str, int & out);

const char * strVal = “abc”;

int val = 0;
strToInt(strVal , val); // Результат операции не проверяется




Слайд 33. Выставить глобальный флаг ошибки

int errorFlag;
#define ERR_NO_ERROR
#define ERR_INCORRECT_INPUT

int strToInt(const char *

str)
{
errorFlag = ERR_NO_ERROR;

errorFlag = ERR_INCORRECT_INPUT;
return 0;

}

int main()
{

const int val = strToInt (strVal); // функция вернет 0
If (errorFlag != ERR_NO_ERROR)
{

}

}




Слайд 4Базовый синтаксис try..catch…throw
try
{
throw T1();

throw T2();

throw T3();
} catch(T1 t1)
{

} catch(T2 t2)
{

} catch

(…) // все типы исключений
{

}

Слайд 5class InputError
{

};

int strToInt(const char * str) {

throw InputError();

}

int main() {

try
{
….

const int value = strToInt(strValue);

} catch(InputError error)
{
std::cout << “Ошибка ввода”<< std::endl;
}

}



Слайд 6Исключение – это один из способов передачи управления

int fun2() {


fun();

}

try
{
fun2();
} catch(std::runtime_error & err)
{

}







Слайд 7Особенности обработчика catch
try
{
throw E();
} catch(H)
{

}

Обработчик catch (H) будет

вызван, если:
Если Н того же типа что и Е;
Если Н является открытой базой Е;
Будет выполнено для указателей и ссылок если выполняется [1] или [2];

Слайд 8Особенности обработчика catch
try
{
throw 4;

// выбросили исключение типа int
} catch(int errNum) // попали в обработчик исключения типа int
{

}

Обработчик catch (H) будет вызван, если:
Если Н того же типа что и Е
Если Н является открытой базой Е
Будет выполнено для указателей и ссылок если выполняется [1] или [2]

Слайд 9Особенности обработчика catch
try
{
throw std::runtime_error;
} catch(std::exception err)
{

}

Обработчик catch (H)

будет вызван, если:
Если Н того же типа что и Е
Если Н является открытой базой Е
Будет выполнено для указателей и ссылок если выполняется [1] или [2]

Слайд 10Перехват всех исключений и повторная генерация
try
{

} catch(…) // перехватить все типы

исключений
{

throw; //выброcить еще раз то же самое исключение

}

Слайд 11Порядок следования catch - секций
try
{

}
catch (int numErr)
{

}
catch

(std::exception exc)
{
...
}
catch(std::runtime_error exc)
{
...
}



Слайд 12Порядок следования catch - секций
try
{
throw std::runtime_error (“”);
}
catch(std::runtime_error

exc) // сработает
{

}
catch (std::exception exc)
{

}
catch(…)
{

}

Слайд 13Иерархия классов исключений и секция catch
try
{
throw SpecialException();
} catch (BaseException

exc)
{
cout << “Error occurred, code = ”
<< exc.errorCode() << endl;
}



class BaseException
{
public:
virtual ~BaseException() { }
virtual int errorCode() const { return -1; }
};

class SpecialException : public BaseException
{
public:
virtual int errorCode() const { return -10; }
};


Слайд 14Иерархия классов исключений и секция catch
try
{
throw SpecialException();
} catch (const

BaseException & exc)
{
cout << “Error occurred, code = ”
<< exc.errorCode() << endl;
}

class BaseException
{
public:
virtual ~BaseException() { }
virtual int errorCode() const { return -1; }
};

class SpecialException : public BaseException
{
public:
virtual int errorCode() const { return -10; }
};



Слайд 15Принцип RAII и исключения RAII - Resource Acquisition Is Initialization


Слайд 16bool fun()
{

Dictionary *

dict = new Dictionary();
If (!dict->loadDictionary(path)) {
delete dict;
return false;
}
EncodingConverter * converter = new EncodingConverter ();
If (!converter->init()) {
delete dict;
delete converter ;
return false;
}
OperationController *controller = new OperationController(dict, converter);
If (!controller->init()) {
delete dict;
delete converter ;
delete controller ;
return false;
}
// некоторые действия и также вызов освобождение dict, converter , controller
}




Слайд 17void fun()
{
// захватить ресурс 1

// захватить ресурс 2

// захватить ресурс N

// использование ресурсов

// освободить ресурс 1
// освободить ресурс 2

// освободить ресурс N
}



Слайд 18Решение 1

bool fun()
{

Dictionary

* dict = new Dictionary();
EncodingConverter * converter = new EncodingConverter ();
OperationController controller = new OperationController(dict, converter);

try
{
If (!dict->loadDictionary(path))
throw DictionaryInitError();

} catch(…)
{
delete dict;
delete converter ;
delete controller ;
return false;
}

delete dict;


return true;
}



Слайд 19Решение 2

class AutoDictionary
{
public:
AutoDictionary(Dictionary * dict) : mDict(dict)

{ }
~AutoDictionary() { delete mDict;}
Dictionary *operator->() { return mDict; }
private:
Dictionary * mDict;
};



Слайд 20Решение 2

void fun()
{

AutoDictionary

dict(new Dictionary());
AutoEncodingConverter converter(new EncodingConverter ());
AutoOperationController controller (new OperationController(dict.get(), converter.get()));

if (!dict->loadDictionary(path))
throw DictionaryInitError();

if (!converter->init())
throw ConverterInitError();

if (!controller->init())
throw ControllerinitError();


}


Слайд 21Решение 3

void fun()
{

std::auto_ptr

dict(new Dictionary());
std::auto_ptr converter(new EncodingConverter ());
std::auto_ptr controller (new OperationController(dict.get(), converter.get()));

If (!dict->loadDictionary(path))
throw DictionaryInitError();

If (!converter->init())
throw ConverterInitError();

If (If (!controller->init())
throw ControllerinitError();


}


Слайд 22bool fun()
{

std::auto_ptr dict(new Dictionary());
std::auto_ptr converter(new EncodingConverter ());
std::auto_ptr controller (new OperationController(dict.get(), converter.get()));

if

(!dict->loadDictionary(path))
return false;

if (!converter->init())
return false;

if (!controller->init())
return false;

}


Слайд 23преобразования типов
Допускается для:
Для наследуемых типов;
Из типизированного в нетипизированный указатель (void *

);

try
{
throw “Error”; // тип cont char *
throw new std::runtime_error(“”); // тип std::runtime_error *
}
catch(void * ptr) // перехватить все исключения типа “указатель”
{

}

Слайд 24Неперехваченные исключения
int main()
{
throw 4;
}

int main()
{
try
{

} catch(…)
{

}
}

std::terminate()

-> abort()

Слайд 25
Спецификация исключений на уровне определения функций
void fun() throw (x1, x2);

void fun()

throw (std::runtime_error, int);

void fun()
{
try
{

}
catch (std::runtime_error) { throw; }
catch (int) { throw; }
catch(…)
{
std::unexpected();
}
}



std::unexpected() - >std::terminate() -> abort()


Слайд 26void f(); // может генерировать любое исключение

void f() throw(); // не

генерирует исключений

void f() throw(std::exception, int); // генерирует исключения типа int, std::exception и
// производные от std::exception

void fun() throw()
{
throw 1;
}

int main()
{
fun();
return 0;
}





Слайд 27class A
{
public:
virtual ~A() { }

virtual void f();

virtual void g() throw(X, Y);
virtual void h() throw(X);
};

class B : public A
{
public:
virtual void f() throw(X);
virtual void g() throw(X);
virtual void h() throw(X, Y);
};

Слайд 28Неожиданные исключения и std::bad_exception
1. std:: bad_exception
void f() throw(X, std::bad_exception)
{

throw 1; //выбрасываем

исключение типа int (будет выброшено std::bad_exception)

}

2. unexpected_handler
typedef void(*unexpected_handler);
unexpected_handler set_unexpected(unexpected_handler) throw( );



Слайд 29Исключения в конструкторах
Без использования исключений:
Сконструировать объект с некорректным состоянием

class A
{
public:

A();
bool isValidConstructed() const;
};

A a;
If (!a. isValidConstructed())
{

}


Слайд 302. Присвоить значение глобальной переменной;
3. Не делать инициализации в конструкторе и

сделать отдельную функцию инициализации.
class A
{
public:
A() {}
bool init();
};


Слайд 31Пометить объект как неинициализированный и во всех функциях проверять состояние объекта;

const

int gErrCodeInitError=-2;

class A
{
public:
A()
{

mInitialized = false;

}

int fun()
{
If (! mInitialized )
return gErrCodeInitError;

}
private:
bool mInitialized;
};


Слайд 32class DBConnectionWrapper
{
public:
DBConnectionWrapper(const std:string & username, const std::string & psw)

: mConnection(NULL)
{
mConnection = new db::DBConnection();
std::string error;
if (mConnection->connect(username, psw, error))
throw DBConnectionFailed(error);
}

private:
db::DBConnection * mConnection;
};

try
{
DBConnectionWrapper dbConnectionWrapper (username, psw);

} catch(DBConnectionFailed & exc)




Слайд 33class DBConnectionWrapper
{
public:
DBConnectionWrapper(const std:string & username, const std::string & psw)

: mConnection(NULL)
{
mConnection = new db::DBConnection();
std::string error;
if (mConnection->connect(username, psw, error))
throw DBConnectionFailed(error);
}

~ DBConnectionWrapper()
{
delete mConnection; // Не сработает, если в конструкторе было исключение
}

private:
db::DBConnection *mConnection;
};
Удаляются только полностью сконструированные объекты!!!




Слайд 34class DBConnectionWrapper
{
public:
DBConnectionWrapper(const std:string & username, const std::string & psw)

: mConnection(NULL)
{
try
{
mConnection = new db::DBConnection();
std::string error;
if (mConnection->connect(username, psw, error))
throw DBConnectionFailed(error);
} catch(…)
{
delete mConnection ;
throw;
}
}

private:
db::DBConnection *mConnection;
};




Слайд 35class DBConnectionWrapper
{
public:
DBConnectionWrapper(const std:string & username, const std::string & psw)
try

: mConnection(NULL)
{
mConnection = new db::DBConnection();
std::string error;
if (mConnection->connect(username, psw, error))
throw DBConnectionFailed(error);
} catch(…)
{
delete mConnection ;
throw;
}

private:
db::DBConnection *mConnection;
};




Слайд 36class DBConnectionWrapper {
public:
DBConnectionWrapper(const std:string & username, const std::string &

psw)
: mConnection(new db::DBConnection())
{
std::string error;
if (mConnection->connect(username, psw, error))
throw DBConnectionFailed(error);
}

private:
AutoConnection mConnection;
};

AutoConnection {
public:
AutoConnection(db::DBConnection *connection) : mConnection(connection) { }
~AutoConnection() { delete mConnection; }
db::DBConnection * operator->() { return mConnection; }
private:
db::DBConnection * mConnection;
};



Слайд 37Использование smart pointer

class DBConnectionWrapper
{
public:
DBConnectionWrapper(const std:string & username, const std::string

& psw)
: mConnection(new db::DBConnection())
{
std::string error;
if (mConnection->connect(username, psw, error))
throw DBConnectionFailed(error);
}

private:
std::auto_ptr< db::DBConnection> mConnection;
};




Слайд 38Исключения в деструкторах
class DBConnectionWrapper
{
public:
DBConnectionWrapper(const std:string & username, const std::string

& psw);
~DBConnectionWrapper()
{
mConnection->close(error); // может быть сгенерировано исключение
}
private:
std::auto_ptr< db::DBConnection> mConnection;
};

Деструктор объекта вызывается в следующих случаях:
Выход из области видимости или оператор delete;
В процессе обработки исключения: в процессе раскручивания стека;


Слайд 39Деструктор объекта вызывается в следующих случаях:
Выход из области видимости или оператор

delete;
В процессе обработки исключения: в процессе раскручивания стека;

void makeQuery(std::string sql)
{

DBConnectionWrapper connection(username, psw);


If (!connection.query(sql))
throw QueryFailed(); // автоматически будет вызван ~DBConnectionWrapper

}


Слайд 40class DBConnectionWrapper
{
public:
DBConnectionWrapper(const std:string & username, const std::string & psw);

~DBConnectionWrapper()
{
try
{
mConnection->close(error); // может быть сгенерировано исключение
} catch(…)
{

}
}
private:
std::auto_ptr< db::DBConnection> mConnection;
};



Слайд 41Стандартные исключения
exception
logic_error
runtime_error
length_error
domain_error
out_of_range
invalid_argument
bad_alloc
bad_exception
io_base::failure
bad_typeid
bad_cast
range_error
overflow_error
underflow_error


Слайд 421. std::bad_alloc
SomeClass sc = new SomeClass(); //

может быть сгенерировано исключение std::bad_alloc

2. std::bad_cast
B & b = dynamic_cast(a); // может быть сгенерировано исключение std::bad_cast

3. std::bad_exception
Для спецификации исключений



Слайд 43Гарантия безопасности исключений
Уровни гарантий:
1. no throw guarantee;
2. strong exception safety (commit

or rollback semantics);
3. basic exception safety;
4. Minimal exception safety;
5. No exception safety;



Слайд 44class Node
{
int mData;
Node * mPNext;
}

class IntList
{
public:

void add(int value)
{
mCachedSize ++;
Node *

node = new Node(); // возможно исключение std::bad_alloc

}

Unsigned int size() const { return mCachedSize; }
private:

unsigned int mCachedSize;
};

1. no throw guarantee;
2. strong exception safety (commit or rollback semantics);
3. basic exception safety;
4. Minimal exception safety;
5. No exception safety;



Слайд 45class Node
{
int mData;
Node * mPNext;
}

class IntList
{
public:

void add(int value) throw (std::bad_alloc)
{
mCachedSize

++; // некорректное значение размера
Node * node = new Node(); // возможно исключение std::bad_alloc

}

Unsigned int size() const { return mCachedSize; }
private:

unsigned int mCachedSize;
};

1. no throw guarantee;
2. strong exception safety (commit or rollback semantics);
3. basic exception safety;
4. Minimal exception safety;
5. No exception safety;



Слайд 46class Node
{
int mData;
Node * mPNext;
}

class IntList
{
public:

void add(int value) throw (std::bad_alloc)
{
Node *

node = new Node(); // возможно исключение std::bad_alloc

mCachedSize ++; // Увеличить размер только после полностью завершенной
// операции
}

Unsigned int size() const { return mCachedSize; }
private:

unsigned int mCachedSize;
};

1. no throw guarantee;
2. strong exception safety (commit or rollback semantics);
3. basic exception safety;
4. Minimal exception safety;
5. No exception safety;



Слайд 47class T1;
class T2;

class A
{
public:

A & operator=(const A & obj)
{
mT1 =

obj.mT1;
mT2 = obj.mT2;
return *this;
}

private:
T1 mT1;
T2 mT2;
};

1. no throw guarantee;
2. strong exception safety (commit or rollback semantics);
3. basic exception safety;
4. Minimal exception safety;
5. No exception safety;


Гарантия безопасности и operator=


Слайд 48class T1;
class T2;

class A
{
public:

A & operator=(const A & obj)
{
mT1 =

obj.mT1;
mT2 = obj.mT2; // может произойти исключение
return *this;
}

private:
T1 mT1;
T2 mT2;
};

1. no throw guarantee;
2. strong exception safety (commit or rollback semantics);
3. basic exception safety;
4. Minimal exception safety;
5. No exception safety;


Гарантия безопасности и operator=


Слайд 49class A
{
public:

A & operator=(const A & obj)
{
A tmp(obj);
swap(tmp);
return *this;
}

private:
void swap(A

& a) throw();

T1 mT1;
T2 mT2;
};

1. no throw guarantee;
2. strong exception safety (commit or rollback semantics);
3. basic exception safety;
4. Minimal exception safety;
5. No exception safety;


Гарантия безопасности и operator=


Обратная связь

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

Email: Нажмите что бы посмотреть 

Что такое ThePresentation.ru?

Это сайт презентаций, докладов, проектов, шаблонов в формате PowerPoint. Мы помогаем школьникам, студентам, учителям, преподавателям хранить и обмениваться учебными материалами с другими пользователями.


Для правообладателей

Яндекс.Метрика