Справочное руководство по C++ - [46]

Шрифт
Интервал

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

R.14.6 Функции-члены шаблонов типа

Функция-член шаблонного класса считается неявной шаблонной функцией, а параметры шаблона типа для ее класса - ее шаблонными параметрами. Приведем пример, в котором описаны три шаблона типа для функции:

>template‹class T› class vector {

> T* v;

> int sz;

>public:

> vector(int);

> T& operator[](int);

> T& elem(int i) { return v[i]; }

> //…

>};

Функцию, выполняющую индексацию, можно определить следующим образом:

>template‹class T› T& vector‹T›::operator[](int i)

>{

> if (i‹0 || sz›=i) error("vector: range error");

> return v[i];

>}

Шаблонный параметр для vector‹T›::operator[]() будет задаваться тем типом vector, к которому применяется операция индексации.

>vector‹int› v1(20);

>vector‹complex› v2(30);


>v1[3] = 7; // vector‹int›::operator[]()

>v2[3] = complex(7,8); // vector‹complex›::operator[]()

R.14.7 Друзья

Функция-друг для шаблона типа не является неявной шаблонной функцией, например:

>template‹class T› class task {

> //…

> friend void next_time();

> friend task‹T›* preempt(task‹T›*);

> friend task* prmt(task*); // ошибка

> //…

>};

Здесь функция next_time() становится другом всех классов task, а каждый класс task имеет в качестве друга функцию preempt() c соответствующими типами параметров. Функцию preempt() можно определить как шаблон типа.

>template‹class T›

>task‹T›* preempt(task‹T›* t) {/*… */}

Описание функции prmt() является ошибочным, поскольку типа task не существует, а есть только специальные шаблонные типы task‹int›, task‹record›, и т.д.

R.14.8 Статические члены и переменные

Для каждого шаблонного класса или функции, создаваемых по шаблону типа, образуется своя копия статических переменных или членов. Рассмотрим пример:

>template‹class T› class X {

> static T s;

> //…

>};


>X‹int› aa;

>X‹char*› bb;

Здесь в классе X‹int› есть статический член типа int, а в классе X‹char› есть статический член типа char*.

Аналогично, в приведенном ниже примере, функция f(int*) имеет статический член s типа int, а функция f(char**) имеет статический член типа char**:

>template‹class T› f(T* p)

>{

> static T s;

> //…

>}


>void g(int a, char* b)

>{

> f(&a);

> f(&b);

>}

R.15 Обработка особых ситуаций

R.15.1 Обработка особых ситуаций

При обработке особых ситуаций в ходе выполнения программы информация и управление передаются из некоторой точки обработчику особых ситуаций. Обработчик находится в цепочке выполненных вызовов функций. Управление обработчику передается с помощью выражения-запуска, которое может быть только в проверяемом-блоке обработчика или в функции, вызванной из проверяемого-блока.

>проверяемый-блок:

> try составной-оператор список-обработчиков

>список-обработчиков:

> обработчик список-обработчиков >opt

>обработчик:

> catch ( описание-особой-ситуации ) составной-оператор

>описание-особой-ситуации:

> список-спецификаций-типа описатель

> список-спецификаций-типа абстрактный-описатель

> список-спецификаций-типа

> …

>выражение-запуска:

> throw выражение >opt

Конструкция проверяемый-блок является оператором (§R.6), а выражение-запуска - унарным выражением типа void (§R.5). Иногда выражение-запуска называют "точкой запуска", а про функцию, в которой встретилось выражение-запуска, говорят, что она "запускает особую ситуацию. Часть программы, которой передается управление из точки запуска называется обработчиком.

R.15.2 Запуск особой ситуации

При запуске особой ситуации управление передается обработчику. Запуск сопровождается передачей объект, тип которого определяет, какой обработчик должен перехватить особую ситуацию. Так, выражение

>throw "Help!";

может быть перехвачено некоторым обработчиком с типом char*:

>try {

> //…

>}

>catch(const char* p) {

> // здесь обрабатывается особая ситуация в символьных строках

>}

а особая ситуация Overflow (переполнение):

>class Overflow {

> //…

>public:

> Overflow(char,double,double);

>};


>void f(double x)

>{

> //…

> throw Overflow('+',x,3.45e107);

>}

может быть перехвачена обработчиком

>try {

> //…

> f(1.2);

> //…

>}

>catch(Overflow& oo) {

> // здесь обработка особой ситуации типа Overflow

>}

При запуске особой ситуации управление передается ближайшему обработчику соответствующего типа. "Ближайший" - это обработчик, проверяемый-блок которого последним получил управление и оно еще не было передано оттуда. Что такое "соответствующий" тип определяется в §R.15.4.

При выполнении выражения-запуска создается временный объект статического типа, который служит операндом в команде throw, Этот объект используется для инициализации переменной, соответствующего типа, описанной в обработчике. Если не считать ограничений на сопоставление типов (см. §R.15.4) и использование временной переменной, то операнд throw аналогичен параметру функции при вызове (§R.5.2.2) или операнду в операторе return.

Если можно было бы, не меняя смысла программы за счет отказа от вызовов конструкторов и деструкторов для временного объекта (§R.12.1), обойтись совсем без временного объекта, то особую ситуацию можно было бы непосредственно инициализировать в обработчике параметром выражения запуска.


Еще от автора Бьерн Страуструп
C++
C++

С++ – это универсальный язык программирования, задуманный так, чтобы сделать программирование более приятным для серьезного программиста. За исключением второстепенных деталей С++ является надмножеством языка программирования C. Помимо возможностей, которые дает C, С++ предоставляет гибкие и эффективные средства определения новых типов. Используя определения новых типов, точно отвечающих концепциям приложения, программист может разделять разрабатываемую программу на легко поддающиеся контролю части. Такой метод построения программ часто называют абстракцией данных.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Симуляция частичной специализации

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Обработка событий в С++

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.