Г. Шилтд - Самоучитель C++ (PDF) (1114887), страница 56
Текст из файла (страница 56)
Что собой представляют новые операторы приведения типов и для чегоони используются?2. Что собой представляет класс typejnfo?3. С помощью какого оператора определяют тип объекта?4. Дан следующий фрагмент программы. Покажите, как определить, объектом какого типа является указатель р: объектом типа Base или объектомтипа Derived.class Base {virtual void f ( ){}class Derived: public Base (}tint main()Base *p, b_ob;Derived d ob;5. Оператор dynamic_cast успешно завершается только в том случае, еслиобъект, над которым выполняется операция приведения типов, является384Самоучительлибо объектом целевого типа, либо объектомцелевого типа.
(Вставьте нужное слово.)6. Можно ли с помощью оператора dynamic_cast снять атрибут const?от13.1. Пространства именО пространствах имен коротко было рассказано в главе 1, сейчас мы рассмотрим это понятие более подробно. Пространства имен появились в C++относительно недавно. Они предназначены для локализации имен идентификаторов во избежание конфликтов имен (name collisions). В среде программирования C++ сосуществует невероятное количество имен переменных, функций и классов.
До введения понятия пространств имен все этиимена находились в одном глобальном пространстве имен и возникаломножество конфликтов. Например, если вы в своей программе определялифункцию toupperQ, то она могла бы (в зависимости от списка своих параметров) подменить стандартную библиотечную функцию (oupperO, поскольку имена обеих функций хранились бы в одном глобальном пространствеимен. Конфликты имен имеют место, когда в одной и той же программеиспользуются библиотеки функций и классов разных производителей.В этом случае вполне возможно — и даже очень вероятно, — что имена, определенные в одной библиотеке, будут конфликтовать с теми же именами,но определенными в другой библиотеке.Все проблемы решило введение понятия пространств имен и ключевогослова namespace.
Это ключевое слово позволяет локализовать область видимости имен, объявленных в данном пространстве имен. Пространство имендает возможность использовать одно и то же имя в разных контекстах и приэтом почвы для конфликтов не возникает. Вероятно, больше всего выигралаот введения пространств имен стандартная библиотека C++ (C++ standardlibrary). В ранних версиях языка вся библиотека C++ определялась в глобальном пространстве имен. Теперь библиотека C++ определяется в собственном пространстве имен std, что значительно снижает вероятность конфликтов имен.
Вы также можете создавать в программе свои собственныепространства имен, чтобы локализовать область видимости тех имен, которые, по вашему мнению, могли бы вызывать конфликты. Это особенноважно при создании собственных библиотек классов или функций.Ключевое слово namespace путем объявления именованных областей даетвозможность разделить глобальное пространство имен. По существу, пространство имен определяет область видимости. Ниже приведена основнаяформа использования ключевого слова namespace:namespace имя {I/ объявленияГлава 13. Пространства имен и другие темы355Все, что определено внутри инструкции namespace, находится внутри области видимости данного пространства имен.Ниже приведен пример объявления пространства имен MyNameSpace:namespace MyNameSpace {int i, k;void myfunc(int j) { cout « j; }class myclass {public:void seti(int x) { i = x; }int geti{) { return i; }Здесь имена переменных i и k, функции myfunc(), а также класса myclassнаходятся в области видимости, определенной пространством имен MyNameSpace.К идентификаторам, объявленным в пространстве имен, внутри этого пространства можно обращаться напрямую.
Например, в пространстве именMyNameSpace в инструкции return i переменная i указана явно. Однако поскольку ключевое слово namespace определяет некоторую область видимости, то при обращении извне пространства имен к объектам, объявленнымвнутри этого пространства, следует указывать оператор расширения областивидимости. Например, чтобы присвоить значение 10 переменной i в тойчасти программы, которая не входит в пространство имен MyNameSpace,необходимо использовать следующую инструкцию:MyNameSpace::i = 10;А чтобы объявить объект типа myclass в той части программы, которая невходит в пространство имен MyNameSpace, нужна такая инструкция:MyNameSpace:imyclass ob;Таким образом, для доступа к члену пространства имен извне этого пространства перед именем члена следует указать имя пространства имен соператором расширения области видимости.Можно себе вообразить, что если в вашей программе обращения к членампространства имен происходят достаточно часто, необходимость каждый разуказывать имя пространства имен и оператор расширения области видимости может быстро надоесть.
Для решения этой проблемы была разработанаинструкция using. У этой инструкции имеются две основные формы:using namespace имя;using имя; .-член;386Самоучитель C++В первой форме параметр имя задает имя пространства имен, доступ к которому вы хотите получить. При использовании этой формы инструкцииusing все члены, определенные в указанном пространстве имен, становятсядоступными в текущем пространстве имен и с ними можно работать напрямую, без необходимости каждый раз указывать имя пространства и операторрасширения области видимости. При использовании второй формы инструкции using видимым делается только указанный в инструкции член пространства имен.
Например, пусть у нас имеется описанное выше пространство имен MyNameSpace, тогда правильны все представленные ниже инструкции using и операторы присваивания:using MyNameSpace::k; // видимой делается только переменная kk = 10; // инструкция правильна, поскольку переменная k видимаusing namespace MyNameSpace; // видимыми делаются все члены// пространства имен MyNameSpacei = 10; // инструкция правильна, поскольку видимы все члены// пространства имен MyNameSpaceИмеется возможность объявить более одного пространства имен с одним итем же именем. Это позволяет разделить пространство имен на несколькофайлов или даже разделить пространство имен внутри одного файла.
Рассмотрим следующий пример:namespace NS {int i;namespace NS {int j ;Здесь пространство имен NS разделено на две части. Несмотря на это, содержимое каждой части по-прежнему остается в одном и том же пространстве имен — пространстве NS.Пространство имен должно объявляться вне всех остальных областей видимости за исключением того, что одно пространство имен может быть вложено в другое. То есть вложенным пространство имен может быть только вдругое пространство имен, но не в какую бы то ни было иную область видимости. Это означает, что нельзя объявлять пространства имен, например,внутри функции.Имеется пространство имен особого типа — безымянное пространство имен(unnamed namespace). Безымянное пространство имен позволяет создаватьидентификаторы, являющиеся уникальными внутри некоторого файла. Ниже представлена основная форма безымянного пространства имен:Глава 13.
Пространства имен и другие темы357namespace {// объявленияБезымянные пространства имен дают возможность задавать уникальныеидентификаторы, известные только внутри области видимости одного файла. Таким образом, внутри файла, содержащего безымянное пространствоимен, к членам этого пространства можно обращаться напрямую, без необходимости каких бы то ни было уточнений. Но вне этого файла такие идентификаторы неизвестны.Вам вряд ли понадобится создавать свои пространства имен для небольшихи средних по объему программ.
Однако, если вы собираетесь создавать библиотеки функций или классов, предназначенных для многократного использования, или хотите гарантировать своим программам широкую переносимость, вам следует рассмотреть возможность размещения своих кодов внутри некоторого пространства имен.1. В представленном ниже примере иллюстрируются атрибуты демонстрационных пространств имен.// Демонстрационные пространства имен#include <iostream>using namespace std;// определение первого пространства именnamespace firstNS {class demo (int i;public:demo(int x) ( i = x; }void seti(int x) { i = x; }int geti() { return i; Jchar str[] = "Иллюстрация пространств имен\пint counter;)// определение второго пространства именnamespace secondNS {int x, у;}intmain{}388Самоучитель C++I/ расширяем область видимостиfirstNS::demo ob(10);/* После объявления объекта ob, его функции-члены могутиспользоваться прямо, без какого бы то ни было уточненияпространства имен*/cout « "Значение объекта ob равно: " « ob.geti();cout « endl;ob.seti(99);cout « "Теперь значение объекта ob равно: " « ob.getif);cout « endl;// вводим строку str в текущую область видимостиusing firstNS::str;cout « str;// вводим все пространство имен firstNS// в текущую область видимостиusing namespace firstNS;for(counter=10; counter; counter—)cout « counter « " ";cout « endl;// используем пространство имен secondNSsecondNS::x = 10;secondNS::y = 20;cout « "Переменные x, у равны: " « secondNS::x;cout « ", " « secondNS::y « endl;// вводим все пространство имен secondNS// в текущую область видимостиusing namespace secondNS;demo xob{x), yob(y);•cout « "Значения объектов xob, yob равны: " « xob.geti()cout « ", " « yob.getiU « endl;return 0;После выполнения программы на экран будет выведено следующее:Значение объекта ob равно: 10Теперь значение объекта ob равно: 99Иллюстрация пространств имен10 9 8 7 6 5 4 3 2 1Переменные х, у равны: 10, 20Значения объектов xob, yob равны: 10, 20Глава13.Пространстваименидругиетемы_359Программа иллюстрирует одно важное положение: при совместном использовании нескольких пространств имен одно пространство не подменяетдругое.