Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

     ::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. 

<p id="AutBody_Root632"><strong>A.16. Альтернативные имена</strong></p>

Для имени можно определить альтернативное имя (alias); иначе говоря, можно определить символическое имя, которое будет означать то же самое, что и имя, с которым оно связано (для большинства случаев употребления этого имени).

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* 

<p id="AutBody_Root633"><strong>A.17. Директивы препроцессора</strong></p>

Каждая реализация языка C++ содержит препроцессор (preprocessor). В принципе препроцессор работает до компилятора и преобразовывает исходный код, написанный нами, в то, что видит компилятор. В действительности это действие интегрировано в компиляторе и не представляет интереса, за исключением того, что оно может вызывать проблемы. Каждая строка, начинающаяся символом #, представляет собой директиву препроцессора.

<p id="AutBody_Root634"><strong>A.17.1. Директива #include</strong></p>

Мы широко использовали препроцессор для включения заголовочных файлов. Рассмотрим пример.

#include "file.h"

Эта директива приказывает препроцессору включить содержимое файла file.h в точку исходного текста, где стоит сама директива. Для стандартных заголовков используются угловые скобки (<...>), а не кавычки ("..."). Например:

#include

Это рекомендованная система обозначений для включения стандартных заголовков. 

<p id="AutBody_Root635"><strong>A.17.2. Директива #define</strong></p>

Препроцессор выполняет также определенные манипуляции с символами, которые называются макроподстановками (macro substitution). Например, определим имя символьной строки.

#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 была инкрементирована дважды совершенно неочевидным образом. Макросы чрезвычайно популярны, в основном потому, что программисты на языке С имели мало альтернатив. Обычные заголовочные файлы содержат определения тысяч макросов. Будьте осторожны!

Перейти на страницу:

Похожие книги

97 этюдов для архитекторов программных систем
97 этюдов для архитекторов программных систем

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

Билл де Ора , Майкл Хайгард , Нил Форд

Программирование, программы, базы данных / Базы данных / Программирование / Книги по IT