ݺߣ

ݺߣShare a Scribd company logo
Модуль 4: Дополнительные темы объектно-ориентированного
программирования.
Темы лекции: Пространства имен. Обработка исключений.
Дополнительные темы ООП.
Практическое задание: Обработка исключений.
Тренер: Игорь Шкулипа, к.т.н.
C++ Базовый. Занятие 15
http://www.slideshare.net/IgorShkulipa 2
Пространства имен
http://www.slideshare.net/IgorShkulipa 3
Пространства имен
Пространством имен называется область программы, в пределах которой это имя
должно быть уникальным. Различные категории имён имеют различные
пространства имён. К их числу относятся:
● Пространство имён глобальных объектов. Это пространство образуется множеством
образующих программу программных модулей. Имена глобальных объектов должны
быть уникальны среди множества имён глобальных объектов во всех модулях,
образующих программу.
● Пространство имен поименованных операторов - функций. Имя оператора должно
быть уникально в теле функции, в которой метка была введена в программу.
● Пространство имён структур, классов, объединений и перечислимых типов зависит
от контекста, в котором были объявлены структуры, классы, объединения. Если они
были объявлены в блоке - это пространство будет составлять блок, если они были
объявлены в модуле, таковой областью является программа. C++ помещает эти
имена в общее пространство имён.
● Имена элементов структур, классов, объединений и перечислимых данных должны
быть уникальны в пределах определения структуры, класса, объединения и
перечислимых данных. При этом в разных структурах, классах, объединениях и
перечислимых данных допустимы элементы с одинаковыми именами. Пространством
имён для элементов структур, классов, объединений и перечислимых данных
элементов являются сами структуры, классы, объединения и перечисления.
● Имена переменных и функций, имена пользовательских типов должны быть
уникальны в области определения: глобальные объекты должны иметь уникальное
имя среди всех глобальных объектов и т.д.
http://www.slideshare.net/IgorShkulipa 4
Пользовательские пространства имен
Поскольку пространства с глобальной областью видимости добавляются
к системе, то имеется возможность возникновения конфликта имен.
Это становится особенно актуальным при использовании библиотек,
разработанных различными независимыми производителями.
Использование namespace позволяет разбить глобальное пространство
имен с тем, чтобы решить подобную проблему.
Общая форма namespace:
namespace имя {
// объявление классов
// объявление функций
}
Кроме того, можно использовать безымянное пространство имен:
namespace {
// объявление классов
// объявление функций
}
Безымянное пространство имен позволяет определить уникальность
идентификаторов с областью видимости в пределах единственного
файла.
http://www.slideshare.net/IgorShkulipa 5
Пример
namespace NameSpace
{
int Var1, Var2;
void Function1(int);
void Function2(double);
class Class1 {};
class Class2: public Class1 {};
}
http://www.slideshare.net/IgorShkulipa 6
Обращение к членам пространства имен
Для обращения к членам пространства имен используется
операция доступа «::»
NameSpace::Var1=10;
NameSpace::Class1 class1Instance;
Если члены пространства имен используются в программе часто,
то можно воспользоваться ключевым словом using.
using namespace NameSpace;
Var1=10;
Class1 class1Instance;
http://www.slideshare.net/IgorShkulipa 7
Обработка исключений
http://www.slideshare.net/IgorShkulipa 8
Исключительные ситуации
Исключительная ситуация (exception) представляет собой неожиданное
событие (ошибку) в программе.
В программах исключительные ситуации определяются как классы.
Чтобы заставить программы следить за исключительными ситуациями,
используется оператор try.
Для обнаружения определенной исключительной ситуации используется
оператор catch.
Для генерации исключительной ситуации при возникновении ошибки
используется оператор throw.
Если программа обнаруживает исключительную ситуацию, она вызывает
специальную (характерную для данной исключительной ситуации)
функцию, которая называется обработчиком исключительной
ситуации.
http://www.slideshare.net/IgorShkulipa 9
Try-catch-throw
Для работы с исключениями в С++ используется три ключевых слова:
⚫ try (пытаться) - начало блока исключений;
⚫ catch (поймать) - начало блока, "ловящего" исключение;
⚫ throw (бросить) - ключевое слово, "создающее" исключение.
try
{
c=a/b; // b может быть равно 0
}
catch(int ex1)
{
cout << "Caught exception number: " << ex1 << “n”;
}
catch(double ex2)
{
cout << "Caught exception number: " << ex2 << “n”;
}
http://www.slideshare.net/IgorShkulipa 10
catch и throw
Catch может "ловить" любой тип данных, так же как и throw
может "кинуть" данные любого типа.
То есть следующие фрагменты кода будут правильно работать:
throw SomeClass();
catch (SomeClass& d) {};
Так же можно "поймать" и все исключения:
catch (...) {};
Оператор throw так же можно использовать и без параметров:
throw;
Ни один оператор, следующий за оператором throw (до конца
блока) выполнен не будет.
http://www.slideshare.net/IgorShkulipa 11
Генерация исключений
Когда возбуждается исключительная ситуация, программа
просматривает стек функций до тех пор, пока не находит
соответствующий catch.
Если оператор catch не найден, то программа будет
обрабатывать исключение в стандартном обработчике,
который показывает непонятные для конечного пользователя
сообщения и, обычно, аварийно завершает программу.
Важным моментом является то, что пока просматривается стек
функций, вызываются деструкторы всех локальных классов,
так что нет необходимости заботиться об освобождении
памяти.
http://www.slideshare.net/IgorShkulipa 12
Классы исключений
В С++ исключения, обычно, определяются в виде классов. Например:
class IStackException {
public: virtual string GetText()=0;
};
class StackExceptionEmpty: public IStackException {
public: virtual string GetText() {
return "EXCEPTION: Stack is Emptyn“; }
};
class StackExceptionErrorOnPop: public IStackException {
public: virtual string GetText() {
return "EXCEPTION: Error on POPn“; }
};
class StackExceptionErrorOnPush: public IStackException {
public: virtual string GetText() {
return "EXCEPTION: Error on PUSHn“; }
};
http://www.slideshare.net/IgorShkulipa 13
Классы, генерирующие исключения
template <class Type> struct StackItem {
Type value;
StackItem* Next;
StackItem* Prev;
};
template <class Type> class Stack{
public:
Stack(){};
~Stack(){};
Type Pop() { throw StackExceptionErrorOnPop(); };
void Push(Type) { throw StackExceptionErrorOnPush(); };
bool Empty() { throw StackExceptionEmpty(); }
private:
StackItem<Type> *_stack;
};
http://www.slideshare.net/IgorShkulipa 14
Функция main
void main()
{
for (int iEx=0; iEx<3; iEx++)
{
Stack<int> stack;
try
{
switch (iEx)
{
case 0: stack.Empty(); break;
case 1: stack.Pop(); break;
case 2: stack.Push(1); break;
}
}
catch(IStackException& ex)
{
cout<<ex.GetText().c_str();
}
}
}
Результат:
EXCEPTION: Stack is Empty
EXCEPTION: Error on POP
EXCEPTION: Error on PUSH
http://www.slideshare.net/IgorShkulipa 15
Отладка программ с помощью макроса ASSERT
http://www.slideshare.net/IgorShkulipa 16
Макрос ASSERT
Макрос задается в виде:
ASSERT(value);
Прерывает программу с указанием строки если значение value FALSE.
Этот макрос будет работать только, если определена константа DEBUG.
Пример:
#define DEBUG
void main()
{
for (int x=1;x<10;x++)
{
cout << x << “n”;
ASSERT(x<3);
}
}
http://www.slideshare.net/IgorShkulipa 17
Дополнительные вопросы С++
http://www.slideshare.net/IgorShkulipa 18
explicit
Ключевое слово explicit запрещает автоматическое создание
конвертирующего конструктора.
class DummyClass{
public: DummyClass(int);
}
// …
DummyClass dc = 5; // Сработает автоматическое преобразование int в объект DummyClass
А вот так не сработает, так как автоматическое преобразование
запрещено словом explicit:
class DummyClass{
public: explicit DummyClass(int);
}
// …
DummyClass dc = 5; // Не сработает
DummyClass dc = DummyClass(5); // А так, по-прежнему, сработает
http://www.slideshare.net/IgorShkulipa 19
Виртуальное наследование
В следующей ситуации возникает неоднозначность определения поля a
для класса D.
class A { protected: int a; };
class B: public A {};
class C: public A {};
class D: public B, public C {};
В классе D, в таком случае, будут два поля с именем a и они оба будут
принадлежать классу A. Проблема состоит в определении к какой
переменной идет обращение. Для исключения подобной ситуации
используют виртуальное наследование. Правильный вид объявления в
данном случае будет:
class A { protected: int a; };
class B: public virtual A {};
class C: public virtual A {};
class D: public B, public C {};
http://www.slideshare.net/IgorShkulipa 20
Лабораторная работа №15. Обработка исключений
Создать классы обработки исключений, которые позволяют
обрабатывать исключительные ситуации для класса «Вектор».

More Related Content

C++ Базовый. Занятие 15.

  • 1. Модуль 4: Дополнительные темы объектно-ориентированного программирования. Темы лекции: Пространства имен. Обработка исключений. Дополнительные темы ООП. Практическое задание: Обработка исключений. Тренер: Игорь Шкулипа, к.т.н. C++ Базовый. Занятие 15
  • 3. http://www.slideshare.net/IgorShkulipa 3 Пространства имен Пространством имен называется область программы, в пределах которой это имя должно быть уникальным. Различные категории имён имеют различные пространства имён. К их числу относятся: ● Пространство имён глобальных объектов. Это пространство образуется множеством образующих программу программных модулей. Имена глобальных объектов должны быть уникальны среди множества имён глобальных объектов во всех модулях, образующих программу. ● Пространство имен поименованных операторов - функций. Имя оператора должно быть уникально в теле функции, в которой метка была введена в программу. ● Пространство имён структур, классов, объединений и перечислимых типов зависит от контекста, в котором были объявлены структуры, классы, объединения. Если они были объявлены в блоке - это пространство будет составлять блок, если они были объявлены в модуле, таковой областью является программа. C++ помещает эти имена в общее пространство имён. ● Имена элементов структур, классов, объединений и перечислимых данных должны быть уникальны в пределах определения структуры, класса, объединения и перечислимых данных. При этом в разных структурах, классах, объединениях и перечислимых данных допустимы элементы с одинаковыми именами. Пространством имён для элементов структур, классов, объединений и перечислимых данных элементов являются сами структуры, классы, объединения и перечисления. ● Имена переменных и функций, имена пользовательских типов должны быть уникальны в области определения: глобальные объекты должны иметь уникальное имя среди всех глобальных объектов и т.д.
  • 4. http://www.slideshare.net/IgorShkulipa 4 Пользовательские пространства имен Поскольку пространства с глобальной областью видимости добавляются к системе, то имеется возможность возникновения конфликта имен. Это становится особенно актуальным при использовании библиотек, разработанных различными независимыми производителями. Использование namespace позволяет разбить глобальное пространство имен с тем, чтобы решить подобную проблему. Общая форма namespace: namespace имя { // объявление классов // объявление функций } Кроме того, можно использовать безымянное пространство имен: namespace { // объявление классов // объявление функций } Безымянное пространство имен позволяет определить уникальность идентификаторов с областью видимости в пределах единственного файла.
  • 5. http://www.slideshare.net/IgorShkulipa 5 Пример namespace NameSpace { int Var1, Var2; void Function1(int); void Function2(double); class Class1 {}; class Class2: public Class1 {}; }
  • 6. http://www.slideshare.net/IgorShkulipa 6 Обращение к членам пространства имен Для обращения к членам пространства имен используется операция доступа «::» NameSpace::Var1=10; NameSpace::Class1 class1Instance; Если члены пространства имен используются в программе часто, то можно воспользоваться ключевым словом using. using namespace NameSpace; Var1=10; Class1 class1Instance;
  • 8. http://www.slideshare.net/IgorShkulipa 8 Исключительные ситуации Исключительная ситуация (exception) представляет собой неожиданное событие (ошибку) в программе. В программах исключительные ситуации определяются как классы. Чтобы заставить программы следить за исключительными ситуациями, используется оператор try. Для обнаружения определенной исключительной ситуации используется оператор catch. Для генерации исключительной ситуации при возникновении ошибки используется оператор throw. Если программа обнаруживает исключительную ситуацию, она вызывает специальную (характерную для данной исключительной ситуации) функцию, которая называется обработчиком исключительной ситуации.
  • 9. http://www.slideshare.net/IgorShkulipa 9 Try-catch-throw Для работы с исключениями в С++ используется три ключевых слова: ⚫ try (пытаться) - начало блока исключений; ⚫ catch (поймать) - начало блока, "ловящего" исключение; ⚫ throw (бросить) - ключевое слово, "создающее" исключение. try { c=a/b; // b может быть равно 0 } catch(int ex1) { cout << "Caught exception number: " << ex1 << “n”; } catch(double ex2) { cout << "Caught exception number: " << ex2 << “n”; }
  • 10. http://www.slideshare.net/IgorShkulipa 10 catch и throw Catch может "ловить" любой тип данных, так же как и throw может "кинуть" данные любого типа. То есть следующие фрагменты кода будут правильно работать: throw SomeClass(); catch (SomeClass& d) {}; Так же можно "поймать" и все исключения: catch (...) {}; Оператор throw так же можно использовать и без параметров: throw; Ни один оператор, следующий за оператором throw (до конца блока) выполнен не будет.
  • 11. http://www.slideshare.net/IgorShkulipa 11 Генерация исключений Когда возбуждается исключительная ситуация, программа просматривает стек функций до тех пор, пока не находит соответствующий catch. Если оператор catch не найден, то программа будет обрабатывать исключение в стандартном обработчике, который показывает непонятные для конечного пользователя сообщения и, обычно, аварийно завершает программу. Важным моментом является то, что пока просматривается стек функций, вызываются деструкторы всех локальных классов, так что нет необходимости заботиться об освобождении памяти.
  • 12. http://www.slideshare.net/IgorShkulipa 12 Классы исключений В С++ исключения, обычно, определяются в виде классов. Например: class IStackException { public: virtual string GetText()=0; }; class StackExceptionEmpty: public IStackException { public: virtual string GetText() { return "EXCEPTION: Stack is Emptyn“; } }; class StackExceptionErrorOnPop: public IStackException { public: virtual string GetText() { return "EXCEPTION: Error on POPn“; } }; class StackExceptionErrorOnPush: public IStackException { public: virtual string GetText() { return "EXCEPTION: Error on PUSHn“; } };
  • 13. http://www.slideshare.net/IgorShkulipa 13 Классы, генерирующие исключения template <class Type> struct StackItem { Type value; StackItem* Next; StackItem* Prev; }; template <class Type> class Stack{ public: Stack(){}; ~Stack(){}; Type Pop() { throw StackExceptionErrorOnPop(); }; void Push(Type) { throw StackExceptionErrorOnPush(); }; bool Empty() { throw StackExceptionEmpty(); } private: StackItem<Type> *_stack; };
  • 14. http://www.slideshare.net/IgorShkulipa 14 Функция main void main() { for (int iEx=0; iEx<3; iEx++) { Stack<int> stack; try { switch (iEx) { case 0: stack.Empty(); break; case 1: stack.Pop(); break; case 2: stack.Push(1); break; } } catch(IStackException& ex) { cout<<ex.GetText().c_str(); } } } Результат: EXCEPTION: Stack is Empty EXCEPTION: Error on POP EXCEPTION: Error on PUSH
  • 16. http://www.slideshare.net/IgorShkulipa 16 Макрос ASSERT Макрос задается в виде: ASSERT(value); Прерывает программу с указанием строки если значение value FALSE. Этот макрос будет работать только, если определена константа DEBUG. Пример: #define DEBUG void main() { for (int x=1;x<10;x++) { cout << x << “n”; ASSERT(x<3); } }
  • 18. http://www.slideshare.net/IgorShkulipa 18 explicit Ключевое слово explicit запрещает автоматическое создание конвертирующего конструктора. class DummyClass{ public: DummyClass(int); } // … DummyClass dc = 5; // Сработает автоматическое преобразование int в объект DummyClass А вот так не сработает, так как автоматическое преобразование запрещено словом explicit: class DummyClass{ public: explicit DummyClass(int); } // … DummyClass dc = 5; // Не сработает DummyClass dc = DummyClass(5); // А так, по-прежнему, сработает
  • 19. http://www.slideshare.net/IgorShkulipa 19 Виртуальное наследование В следующей ситуации возникает неоднозначность определения поля a для класса D. class A { protected: int a; }; class B: public A {}; class C: public A {}; class D: public B, public C {}; В классе D, в таком случае, будут два поля с именем a и они оба будут принадлежать классу A. Проблема состоит в определении к какой переменной идет обращение. Для исключения подобной ситуации используют виртуальное наследование. Правильный вид объявления в данном случае будет: class A { protected: int a; }; class B: public virtual A {}; class C: public virtual A {}; class D: public B, public C {};
  • 20. http://www.slideshare.net/IgorShkulipa 20 Лабораторная работа №15. Обработка исключений Создать классы обработки исключений, которые позволяют обрабатывать исключительные ситуации для класса «Вектор».