Литмир - Электронная Библиотека
A
A

{

  return Date(1970,1,1);

}

Эта функция создает объект типа

Date
каждый раз, когда вызывается функция
default_date()
. Часто этого вполне достаточно, но если функция
default_date()
вызывается часто, а создание объекта класса Date связано с большими затратами, предпочтительнее было бы конструировать его только один раз. В таком случае код мог бы выглядеть так:

const Date& default_date()

{

  static const Date dd(1970,1,1); // инициализируем dd

                                  // только при первом вызове

  return dd;

}

Статическая локальная переменная инициализируется (создается) только при первом вызове функции, в которой она объявлена. Обратите внимание на то, что мы вернули ссылку, чтобы исключить ненужное копирование, и, в частности, вернули константную ссылку, чтобы предотвратить несанкционированное изменение значения аргумента при вызове функции. Рассуждения о передаче аргумента (см. раздел 8.5.6) относятся и к возвращаемому значению.

8.7. Пространства имен

Для организации кода в рамках функции используются блоки (см. раздел 8.4).

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

• Они позволяют определить множество сущностей без опасения, что их имена совпадут с другими именами в программе.

• Позволяют именовать то, что мы определили.

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

Color
,
Shape
,
Line
,
Function
и
Text
(глава 13).

namespace Graph_lib {

  struct Color { /* ... */ };

  struct Shape { /* ... */ };

  struct Line: Shape { /* ... */ };

  struct Function: Shape { /* ... */ };

  struct Text: Shape { /* ... */ };

  // ...

  int gui_main() { /* ... */ }

}

Очень вероятно, что вы также захотите использовать эти имена, но теперь это уже не имеет значения. Вы можете определить сущность с именем

Text
, но ее уже невозможно перепутать с нашим классом, имеющим то же имя. Наш класс называется
Graph_lib::Text
, а ваш класс — просто
Text
. Проблема возникнет только в том случае, если в вашей программе есть класс или пространство имен
Graph_lib
, в которое входит класс
Text
. Имя
Graph_lib
довольно неудачное; мы выбрали его потому, что “прекрасное и очевидное” имя
Graphics
имеет больше шансов встретиться где-нибудь еще.

Допустим, ваш класс

Text
является частью библиотеки для обработки текстов. Та же логика, которая заставила нас разместить графические средства в пространстве имен
Graph_lib
, подсказывает, что средства для обработки текстов следует поместить в пространстве имен, скажем, с именем
TextLib
.

namespace TextLib {

  class Text { /* ... */ };

  class Glyph { /* ... */ };

  class Line { /* ... */ };

  // ...

}

Если бы мы использовали оба пространства имен одновременно, то столкнулись бы с реальной проблемой. В этом случае действительно возникла бы коллизия между именами классов

Text
и
Line
. И что еще хуже, если бы мы были не создателями, а пользователями библиотеки, то не никак не смогли бы изменить эти имена и решить проблему. Использование пространств имен позволяет избежать проблем; иначе говоря, наш класс
Text
— это класс
Graph_lib::Text
, а ваш —
TextLib::Text
. Имя, составленное из имени пространства имен (или имени класса) и имени члена с помощью двух двоеточий,
::
, называют полностью определенным именем (fully qualified name).

8.7.1. Объявления using и директивы using

Писать полностью определенные имена довольно утомительно. Например, средства стандартной библиотеки языка С++ определены в пространстве имен

std
и могут использоваться примерно так:

#include<string>   // доступ к библиотеке string

#include<iostream> // доступ к библиотеке iostream

int main()

{

  std::string name;

  std::cout << " Пожалуйста, введите имя \n";

  std::cin >> name;

  std::cout << " Привет, " << name << '\n';

}

Тысячи раз обращаясь к элементам стандартной библиотеки

string
и
cout
, мы на самом деле вовсе не хотим каждый раз указывать их полностью определенные имена —
std::string
и
std::cout
. Напрашивается решение: один раз и навсегда указать, что под классом
string
мы имеем в виду класс
std::string
, а под потоком
cout
— поток
std::cout
и т.д.

120
{"b":"847443","o":1}