Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Объектно-ориентированное программирование и C++....doc
Скачиваний:
20
Добавлен:
08.07.2019
Размер:
188.42 Кб
Скачать

3.6.2.2 Пространства имен

Большинство нетривиальных приложений состоят из нескольких файлов с исходным текстом программы. Эти файлы могут создаваться и обслуживаться группой программистов. В конце концов, все файлы собираются вместе и проходят через финальную процедуру сборки готового приложения. Традиционно принято, чтобы все имена, не заключенные в некоторой локальной области (функции, теле класса или модуле трансляции), разделяли общие глобальные имена. Поэтому повторное определения имен, обнаруженное в процессе сборки отдельных модулей, приводит к необходимости каким-то образом различать каждое имя. Решение этой проблемы в C++ возложено на механизм пространства имен (namespace).

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

namespace <идентификатор> { [<объявления>] } Существует три способа доступа к элементам идентифицированного пространства имен:

• Явная квалификация доступа к конкретному элементу:

ALPHA :: varl; // доступ к переменной из ALPHA BETA :: Fl; // доступ к функции из BETA

• Доступ ко всем элементам:

using namespace :: ALPHA; // доступ ко всем именам из ALPHA

• Объявление нового идентификатора в локальном пространстве имен:

using :: new_name; // добавление идентификатора

3.6.2.3 Явные объявления

Обычно объектам класса, в котором объявлен конструктор с одним параметром, можно присвоить значения, тип которых автоматически (неявно) преобразуется к своему классовому типу. При объявлении конструктора можно использовать модификатор explicit:

explicit <объявление конструктора> Тогда при объявлении конструкторов данного класса с ключевым словом explicit всем объектам класса можно присвоить только те значения, тип которых явно преобразуется к классовому типу (Листинг 3.19). Другие присваивания приведут к ошибке компиляции.

class X

public:

explicit X(int);

explicit X(const char*, int = 0);

};

void f(X arg)

(

X a = X (1) ;

X b = Х("строка",0);

a = Х(2);

} :(

Листинг 3.19. Явные объявления конструкторов.

Явные объявления конструкторов требуют, чтобы значения в операторах присваивания были преобразованы к тому классовому типу, объектам которого эти значения присваиваются.

3.6.2.4 Непостоянные объявления

При объявлении переменной, которая может быть изменена фоновой задачей, обработчиком прерывания или портом ввода-вывода, используется модификатор volatile:

volatile <тип> <имя объекта>;

В C++ применение ключевого слова volatile распространяется на классы и функции-члены. Это ключевое слово запрещает компилятору делать предположения относительно значения указанного объекта, поскольку при вычислении выражений, включающих этот объект, его значение может измениться в любой момент. Кроме того. непостоянная переменная не может быть объявлена с модификатором register. Листинг 3.20 показывает пример реализации таймера, в котором переменная ticks модифицируется обработчиком временных прерываний.

volatile int ticks;

void timer( ) // Объявление функции таймера

ticks++;

void wait (int interval)

ticks = 0;

while (ticks < interval); // Цикл ожидания

}

Листччг 3.20. Изменение непостоянной переменной volatile.

Положим, что обработчик прерывания timer был надлежащим образом ассоциирован с аппаратным прерыванием от часов реального времени. Процедура wait реализует цикл ожидания, пока значение переменной ticks не станет равным интервалу времени, заданному ее параметром. Компилятор C++ обязан перезагружать значение переменной volatile ticks перед каждым сравнением внутри цикла - несмотря на то, что внутри цикла значение переменной не изменяется. Некоторые оптимизирующие компиляторы могли бы допустить эту "роковую" ошибку.

Другой вид непостоянной переменной, которая может быть изменена даже если она входит в константное выражение, объявляется с помощью модификатора mutable:

mutable <имя переменной>;

Назначение ключевого слова mutable состоит в спецификации членов данных некоторого класса, которые могут быть модифицированы константными функциями этого класса. Листинг 3.21 показывает пример, в котором член данных count модифицируется константной функцией F1.

class A {

public: mutable int count; int F1 (int p = 0) const // Объявление функции F1

count = p++ return count; //PI возвращает count

) I

void main() {

A a;

cout “ a.Fl(3) “ end.1; // main выдает значение 4 )

Листинг 3.21. Изменение непостоянной переменной mutable.

3.6.2.5 Идентификация типов RTTI

Идентификация типов при выполнении программы RTTI (Run-Time Туре Identification) позволяет вам написать переносимую программу, которая способна определять фактический тип объекта в момент выполнения даже в том случае, если программе доступен только указатель на этот объект. Это дает возможность, например, преобразовывать тип указателя на виртуальный базовый класс в указатель на производный тип фактического объекта данного класса. Таким образом, преобразование типов может происходить не только статически - на фазе компиляции, но и динамически - в процессе выполнения. Динамическое преобразование указателя в заданный тип осуществляется с помощью оператора dynamic_cast.

Механизм RTTI также позволяет проверять, имеет ли объект некоторый определенный тип, или принадлежат ли два объекта одному и тому же типу. Оператор typeid определяет фактический тип аргумента и возвращает указатель на объект класса typeinfo, который этот тип описывает.

Передавая RTTI Инспектору объектов во время выполнения, C++Builder информирует его о типах свойств и членов данного класса.