Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 [ 5 ] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239

В отличие от классов пространства имен открыты для новых определений и расширений. Следовательно, пространства имен могут использоваться для определения модулей, библиотек или компонентов, причем даже в разных файлах. Пространства имен определяют логические, а не физические модули (в UML и других аналогичных средствах модули также называются пакетами).

Если какие-либо типы аргументов определены в пространстве имен, в котором определена функция, то при вызове функции уточнять пространство имен не обязательно (так называемое правило Кенига). Пример:

Определение идентификаторов в пространстве имен josuttis class File:

void myGlobalFunc( const РПе&):

josuttis;:F11e Obj;

niyGlobalFunc(obj): По правилу Кенига функция josuttisinnyGlobalFunc

будет успешно найдена

Объявление using помогает избежать утомительных многократных повторений уточняющего префикса. Например, следующее объявление означает, что в текущей области видимости идентификатор File является локальным синонимом для josuttis: :File:

using josuttis:;File;

С другой стороны, директива using открывает доступ ко всем именам заданного пространства имен так, как если бы они были объявлены за его пределами. Это может привести к возникновению обычных конфликтов. Например, представленная ниже директива делает идентификаторы File и myGlobalFunc() глобальными в текущей области видимости:

using namespace josuttis;

Если в глобальной области видимости уже существуют идентификаторы RIe или myGlobalFuncO, то при использовании имен из пространства josuttis без уточняющих префиксов компилятор сообщает о неоднозначности ссылки.

Никогда не используйте директиву using при отсутствии полной информации о контексте (например, в заголовочных файлах, модулях или библиотеках). Директива может изменить область видимости идентификаторов в пространстве имен, что приведет к нарушению работы программы при включении или использовании программного кода другого модуля. Вообще говоря, присутствие директив using в заголовочных файлах считается признаком плохого проектирования.

В стандартной библиотеке С++ все идентификаторы определяются в пространстве имен std. За дополнительной информацией обращайтесь на с. 40.



Тип bool

Для упрощения работы с логическими (булевыми) переменными в стандартную библиотеку включен тип bool. Использование типа bool делает программу более наглядной и позволяет переопределять поведение логических величин. Логические значения представляются литералами tnje и false; поддерживают преобразования типов из bool к целому типу и обратно. Ноль эквивалентен false, любое другое число эквивалентно true.

Ключевое слово explicit

Ключевое слово explicit запрещает автоматическое преобразование типа для конструктора с одним аргументом. Типичный пример ситуации, в которой это необходимо, - класс коллекции (например, стек), конструктору которого при вызове передается начальный размер коллекции:

class Stack {

explicit StackCint size): Создание стека с заданным

исходным размером

В данном случае ключевое слово explicit ифает очень важную роль. Без explicit этот конструктор автоматически определял бы преобразование типа из int в Stack. В этом случае объектам типа Stack можно было бы присваивать тип int:

Stack s;

s = 40: Команда создает новый стек на 40 элементов и присваивает его s.

В результате автоматического преобразования типа число 40 преобразуется в стек из 40 элементов, а результат присваивается s. Вряд ли это именно то, что предполагалось. Но если объявить конструктор Int с ключевым словом explicit, попытка присваивания вызовет ошибку на стадии компиляции.

Учтите, что слово explicit также исключает инициализацию с автоматическим преобразованием типа при присваивании:

Stack sl(40): OK

Stack S2 = 40; ОШИБКА

Дело в том, что между следующими двумя парами строк существует тонкое различие:

X х:

Y у(х): Явное преобразование X х:

Y у = X; Неявное преобразование

В первом фрагменте новый объект типа Y создается явным преобразованием от типа X, тогда как во втором фрагменте новый объект типа Y создается с неявным преобразованием.



Новые операторы преобразования типа

Чтобы профаммисты могли более четко выразить смысл явного преобразования типа с одним аргументом, в стандарт были воючеиы четыре новых оператора.

О static cast

Оператор преобразует значение на логическо.м уровне. Считайте, что он создает временный объект, который затем инициализируется преобразуемыми данными. Преобразование разрешено только при наличии преобразования типа, определенного либо по умолчанию, либо явно. Пример:

float х:

cout « static cast<int>(x): Вывод х в формате int

fCstatlc cast<string>("hello")): Функция fO вызывается для string.

а не для char*

О dynamic ca5t

Оператор позволяет привести полиморфный тип к «настоящему» статическому типу. Это единственное преобразование типа, которое проверяется на стадии выполнения программы; следовательно, оно может использоваться для проверки типов полиморфных значений. Пример:

class Car: Абстрактный базовый класс

(содержит хотя бы одну чисто виртуальную функцию) class Cabriolet : public Car {

class Limousine i public Car {

void f(Car* cp) {

Cabriolet* p = dynamic cast<Cabriolet*>(cp): If (p == NULL) {

p не указывает на объект типа Cabriolet

В данном примере в функции f() определены специальные действия для тех объектов, которые не относятся к «настояп1ему» статическому типу Cabriolet Если аргумент является ссылкой, а преобразование типа завершается неудачей, dynamic cast генерирует исключение bad cast (см. с. 43). Помните, что с точки зрения проектирования при работе с полиморфными типами всегда лучше избегать выбора действий в зависимости от фактического типа.



0 1 2 3 4 [ 5 ] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239