::f(4); // это глобальная функция f (::f)
}
Имена можно явно уточнять именами их пространств имен (например, Foo::f(3)
) или оператором разрешения области видимости ::
(например, ::f(2)
), который относится к глобальному пространству имен.
Все имена в пространстве имен (например, в стандартном пространстве std
) можно сделать доступными с помощью директивы using namespace std
;
Будьте осторожны с директивой using
. Удобство, которое она предоставляет, достигается за счет потенциальной коллизии имен. В частности, старайтесь избегать директив using
в заголовочных файлах. Отдельное имя из пространства имен можно сделать доступным с помощью объявления пространства имен.
using Foo::g;
g(2); // это функция g из пространства имен Foo (Foo::g)
Более подробная информация о пространствах имен содержится в разделе 8.7.
A.16. Альтернативные имена
Для имени можно определить
typedef int* Pint; // Pint — это указатель на int
namespace Long_library_name { /* ... */ }
namespace Lib = Long_library_name; // Lib — это Long_library_name
int x = 7;
int& r = x; // r — это x
Ссылки (см. разделы 8.5.5 и A.8.3) — это механизм указания на объекты, работающий на этапе выполнения программы. Ключевые слова typedef
(см. разделы 20.5 и 27.3.1) и namespace
относятся к механизмам ссылок на имена, работающим на этапе компиляции. В частности, инструкция typedef
не вводит новый тип, а просто задает новое имя существующего типа. Рассмотрим пример.
typedef char* Pchar; // Pchar — это имя типа char*
Pchar p = "Idefix"; // OK: p — это указатель типа char*
char* q = p; // OK: p и q — указатели типа char
int x = strlen(p); // OK: p — указатель типа char*
A.17. Директивы препроцессора
Каждая реализация языка C++ содержит #
, представляет собой директиву препроцессора.
A.17.1. Директива #include
Мы широко использовали препроцессор для включения заголовочных файлов. Рассмотрим пример.
#include "file.h"
Эта директива приказывает препроцессору включить содержимое файла file.h
в точку исходного текста, где стоит сама директива. Для стандартных заголовков используются угловые скобки (<...>
), а не кавычки ("..."
). Например:
#include
Это рекомендованная система обозначений для включения стандартных заголовков.
A.17.2. Директива #define
Препроцессор выполняет также определенные манипуляции с символами, которые называются
#define FOO bar
Теперь везде, где препроцессор увидит символы FOO
, они будут заменены символами bar
.
int FOO = 7;
int FOOL = 9;
В таком случае компилятор увидит следующий текст:
int bar = 7;
int FOOL = 9;
Обратите внимание на то, что препроцессор знает об именах языка С++ достаточно много, чтобы не заменить символы FOO
, являющиеся частью слова FOOL
.
С помощью директивы define
можно также определить макросы, принимающие параметры.
#define MAX(x,y) (((x)>(y))?(x) : (y))
Их можно использовать следующим образом:
int xx = MAX(FOO+1,7);
int yy = MAX(++xx,9);
Эти выражения будут развернуты так:
int xx = (((bar+1)>( 7))?(bar+1) : (7));
int yy = (((++xx)>( 9))?(++xx) : (9));
Подчеркнем, что скобки необходимы для того, чтобы получить правильный результат при вычислении выражения FOO+1
. Кроме того, переменная xx
была инкрементирована дважды совершенно неочевидным образом. Макросы чрезвычайно популярны, в основном потому, что программисты на языке С имели мало альтернатив. Обычные заголовочные файлы содержат определения тысяч макросов. Будьте осторожны!