Пространства имен. Обработка исключений. Дополнительные темы ООП.
1 of 20
Download to read offline
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 {
// объявление классов
// объявление функций
}
Безымянное пространство имен позволяет определить уникальность
идентификаторов с областью видимости в пределах единственного
файла.
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“; }
};
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 {};