Г. Шилтд - Самоучитель C++ (DJVU) (1114955), страница 58
Текст из файла (страница 58)
5. Ранее уже говорилось, что библиотека исходного языка С++ была определена в глобальном пространстве имен. Если вам придется модернизировать старую программу на С++, то вам понадобится либо включить в нее инструкцию вяпя пашеврасе вИ, либо перед каждой ссылкой на члена библиотеки дописывать имя пространства имен с оператором расширения области видимости вИ::.
Это особенно важно, если вы замените прежние заголовочные файлы заголовками нового стиля (без расширения .Ь). Помните, прежние заголовочные файлы размещают свое содержимое в глобальном пространстве имен, а заголовки нового стиля — в пространстве имен вЫ. 6. В языке С, если вы хотите ограничить область видимости глобального имени только тем файлом, в котором это имя объявлено, вы должны объявить его как статическое, т. е. с идентификатором в1а((с.
Например, предположим, что следующие два файла являются частью одной программы: 392 Самоучитель С++ Здесь область видимости переменной еоиа$ег также ограничена первым файлом. Использовать безымянное пространство имен вместо ключевого слова з1аг(с рекомендует новый стандарт Яапдагд С++. 1. Переделайте представленную ниже программу из главы 9 так, чтобы в ней отсутствовала инструкция из(щ павзезрасе з((1. // Превращение пробелов в вертикальные линии Й(пс)аде <1озггеазв> Ь ь'.псЛ.ис(е <бзггеав> нз(пя папзезрасе вМ; (пт пза1п(1пГ агдс, с)заг *агдч(1) 1Г(агап!=3) ( сонг « "преобразование <файл ввода> <файл вывода>~п"; гегпгп 1; 11зсгеазв тз.п (агсззт(1))т // открытие файла для ввода огзггеазв йонг(агозт(21)т // создание файла для вь:вода 1Х (! гонг) сопс « "Файл открыть невозможно~в"," гегпгп 1з ) 1б (! бгп) ( соке « "Файл открыть невозможно~п"з ге игп 1з с] аг с]з; ~1п.
ззпзегг (1оз:: зЫрыз); // не пропускать пробелы ы)з11е (]Г1п. еой () ) ( бз.гз >>сЬ з з.й (с)з=-= ' ' ) с)з = з.г (! ггп, еог () ) болг « сЬ; гап.с1озе(); Хоцг, с1озе () ' гегпгп 0~ Глава 13. Пространства имен идругие темы 393 2. Объясните назначение безымянного пространства имен. 3. Опишите различия между двумя формами инструкции ияпя. 4. Объясните, почему в подавляющее большинство программ данной книги введена инструкция вяпя. Приведите альтернативу ее использованию.
5. Объясните почему, если вы создаете многократно используемый код, его желательно размещать в собственном пространстве имен. 13.2. функции преобразования Иногда бывает полезно преобразовать объект одного типа в объект другого типа. Хотя для этого можно воспользоваться перегруженной оператор- функцией, часто более легким (и лучшим) способом такого преобразования является функция преобразования.
Функция преобразования (сопиегиоп /ипс6ол) преобразует объект в значение, совместимое с другим типом данных, который часто является одним из встроенных типов данных С++. Уточним, функция преобразования автоматически преобразует объект в значение, совместимое с типом выражения, в котором этот объект используется.
Здесь показана основная форма функции преобразования: орегаЕог тип О Г теглтт1 аиачеттиа.' ) Здесь тип — это целевой тип преобразования, а значение — это значение объекта после выполнения преобразования. Функции преобразования возвращают значение типа тип. У функции преобразования не должно быть параметров, и она должна быть членом класса, для которого выполняется преобразование. Как будет показано в примерах, обычно функция преобразования обеспечивает более ясный подход к преобразованию значения объекта в другой тип, чем любой другой метод С++, поскольку она позволяет явно включить объект в выражение, содержащее переменные целевого типа.
1, В следующей программе класс соогй содержит функцию преобразования, которая преобразует объект в целое. В данном случае функция возвращает произведение двух координат; однако в каждом конкретном случае допускаетсялюбое необходимоедействие. // Простой пример функции преобразования 111пс1иде <1.ов~теахп> ияпК пагпезрасе веФ 394 Самоучитель С++ с1аяя соогб ( 1пп х, у; ри)з11с: Соого(ъпе 1, 1пг З) ( х = 1 у орегапог 1пТ() 1 геппгп х*у; ) !1 Функция преобразования 1пс ваъпО соотг о1(2, 3), о2(4, 3) у 1пг 1; = о1; 1! обьект о1 автоматически преобразуется в целое сопс « 1 « 'Хп'; 100 4 о21 !! объект о2 преобразуется в целое соШ « 1 « '~п'; тебп гп О; В результате выполнения этой программы на экран будут выведены значения б и 112. Обратите внимание, что функция преобразования вызывается тогда, когда объект о1 присваивается целому, а также когда объект о2 используется, как часть большого выражения, оперирующего с целыми.
Как уже установлено, с помощью функции преобразования вы разрешаете вставлять объекты созданных вами классов в "обычные" выражения, без образования сложных цепочек перегруженных оператор-функций. 2. Следующим представлен другой пример функции преобразования. Здесь преобразуется строка типа з1гтуре в символьный указатель на згг. п(пс1пде <ьовггеак> Фьпс1ис)е <сзгппа> из(па пагпезрасе зМг с1азз яггтуре ( сваг впг(ВО) ) )пг 1еп; рп)а11с: зсггуре (спаг *з) ( зегсру(всг, я); 1еп = згг1еп(з) ) ) орегагог спал *() ( гепцгп ясг; ) !! преобразование в тип спал " » 1пс ваап () ( ят.псуре в ("Это проверка ~п" ); спаг "р, з2(60); ~з. Пространства имен и другие Глава темы М5 р = з; // преобразование в тип сЬаг * сош « "Это строка: " « р « ''~п'; // при вызове функции преобразуется в тип сЬаг * зггсру~з2, в); сонг « "Это копия строки; " « з2 « ''~п'; гегигп О; Эта программа выводит на экран следующее: Это строка: Это проверка Это копия строки: Это проверка Как можно заметить, функция преобразования вызывается не только при присваивании объекта з объекту р (который имеет тип сЬаг *), но она также используется как параметр для функции зГгсруО.
Вспомните, функция а$гсруО имеет следующий прототип: сЬаг +вМксру[сЬак ~а1, сопят сЬаг ~з2) Поскольку прототип определяет, что объект в2 имеет тип сваг ~, функция преобразования объекта в тип сваг * вызывается автоматически. Этот пример показывает, как функция преобразования может помочь интегрировать ваши классы в библиотеку стандартных функций С++. 1. Используя класс вггГуре из примера 2, создайте функцию преобразования для превращения строки в целое. Функция преобразования должна возвращать длину строки, хранящейся в Мг, Покажите, что ваша функция преобразования работает. 2.
Пусть дан класс с1азв Риг афпг Ьаае; ~ пг ехр; раЬ1з.с: ритйпе Ь, 1пг е) ~ Ьазе - Ь; ехр = е; ) // здесь создайте функцию преобразования в целое 3. Создайте функцию преобразования для превращения объекта типа рзгг в целое. Функция должна возвращать результат возведения в степень Ьаяе'"а. 13.3. Статические члены класса Самоучитель С++ Переменные — члены класса можно объявлять как статические (згаГ1с). Используя статические переменные-члены, можно решить несколько непростых проблем. Если вы объявляете переменную статической, то может существовать только одна копия этой переменной — независимо от того, сколько объектов данного класса создается. Каждый объект просто использует (совместно с другими) эту одну переменную. Запомните, для обычных переменных-членов при создании каждого объекта создается их новая копия, и доступ к каждой копии возможен только через этот объект.
(Таким образом, для обычных переменных каждый объект обладает собственными копиями переменных.) С другой стороны, имеется только одна копия статической переменной — члена класса, и все объекты класса используют ее совместно. Кроме этого, одна и та же статическая переменная будет использоваться всеми классами, производными от класса, в котором эта статическая переменная содержится. Может показаться необычным то, что статическая переменная — член класса создается еще до того, как создан объект этого класса.
По сути, статический член класса — это просто глобальная переменная, область видимости которой ограничена классом, в котором она объявлена. В результате, как вы узнаете из следующих примеров, доступ к статической переменной-члену возможен без всякой связи с каким бы то ни было объектом. Когда вы объявляете статические данные-члены внутри класса, вы не определяете их. Определить их вы должны где-нибудь вне класса. Для того чтобы указать, к какому классу статическая переменная принадлежит, вам необходимо переобъявить (гедес1аге) ее, используя операцию расширения области видимости. Все статические переменные-члены по умолчанию инициализируются нулем. Однако, если это необходимо, статической переменной класса можно дать любое выбранное начальное значение.
Запомните, что основной смысл поддержки в С++ статических переменных-членов состоит в том, что благодаря им отпадает необходимость в использовании глобальных переменных. Как можно предположить, если при работе с классами задавать глобальные переменные, то это почти всегда нарушает принцип инкапсуляции, являющийся фундаментальным принципом ООР и С++. Помимо переменных-членов статическими можно объявлять и функции- члены, но обычно это не делается. Доступ к объявленной статической функции — члену класса возможен только для других статических членов этого класса. (Естественно, что доступ к объявленной статической функции — члену класса возможен также и для глобальных данных и функций.) У статической функции-члена нет указателя ЙЬ.
Статические функции- члены не могут быть виртуальными. Статические функции-члены не могут Глава 13. Пространства имен и другие темы объявляться с идентификаторами сопв1 (постоянный) и уо!аде (переменный). И наконец, статические функции — члены класса могут вызываться любым объектом этого класса, а также через имя класса и оператор расширения области видимости без всякой связи с каким бы то ни было объектом этого класса. 1. Простой пример использования статической переменной-члена. Пример статической переменной — члена ссгпс1пг)е <1овддеат> пятна паглеярасе вЫ) с1аяя лгус1авв ( яеаягс гпс 1; рп)Ыъс: чогг) ведь(1пс п) ( .'.