Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Информатика Экзамен

.pdf
Скачиваний:
10
Добавлен:
02.05.2015
Размер:
738.97 Кб
Скачать

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

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

C++

Пространство имён определяется блоком инструкций:

namespace foo {

int bar;

}

Внутри этого блока идентификаторы могут вызываться именно так, как они были объявлены. Но вне блока требуется указание имени пространства имён перед идентификатором. Например, вне namespace foo идентификатор bar должен указываться как foo::bar. C++ содержит некоторые другие конструкции, делающие подобные требования необязательными. Так, при добавлении строки

using namespace foo;

в код, указывать префикс foo:: больше не требуется. Ещё пример:

namespace Namespace12

{

int foo=0;

}

void func1()

{

using namespace Namespace12;

// теперь все имена из пространства имён Namespace12 будут видны здесь без дополнительных префиксов

++foo;

}

void func2()

{

// а тут имя нужно уточнить:

Namespace12::foo = 42;

}

Код, не объявленный явным образом в пространстве имён, подразумевается объявленным в глобальном пространстве имён.

Разрешение пространств имён в C++ иерархично. Это означает, что в гипотетическом пространстве имён еда::суп, идентификатор курица будет обозначать еда::суп::курица (если пространство существует). Если не существует, то тогда он указывает на еда::курица (если это пространство существует). Если и это пространство не существует, то курица ссылается на идентификатор в глобальном пространстве.

Зачастую пространства имён в C++ используются для избежания коллизий имён

namespace {

int a;

void f() { /*...*/ }

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

}

Нельзя осуществить доступ из одной единицы трансляции к члену анонимного пространства имён из другой единицы.

Хотя пространства имён широко используются в современном коде, большая часть старого кода не имеет подобных возможностей. Например, вся стандартная библиотека языка C++ определена внутри namespace std, но до стандартизации многие компоненты первоначально были определены в глобальном пространстве.

Также можно сделать видимым не всё пространство, а отдельные имена внутри него, например:

namespace foo {

int bar;

int somelse;

}

int main () {

using foo::bar; //Делает видимым только bar, somelse невидим!

}

25.

В языке программирования C++ термин Стандартная Библиотека означает коллекцию классов и функций, написанных на базовом языке. Стандартная Библиотека поддерживает несколько основных контейнеров, функций для работы с этими контейнерами, объектов-функции, основных типов строк и потоков (включая интерактивный и файловый ввод-вывод), поддержку некоторых языковых особенностей, и часто используемые функции для выполнения таких задач, как, например, нахождение квадратного корня числа. Стандартная Библиотека языка C++ также включает в себя спецификации стандарта ISO C90 стандартной библиотеки языка Си. Функциональные особенности Стандартной Библиотеки объявляются внутри пространства имен std.

Стандартная библиотека шаблонов (STL) — подмножество стандартной библиотеки C++ и содержит контейнеры, алгоритмы, итераторы, объекты-функции и т. д.[источник не указан 1533 дня] Хотя некоторые программисты используют термин «STL» вместо (или попеременно) с термином «Стандартная библиотека C++».

Заголовочные файлы стандартной библиотеки C++ не имеют расширения «.h».

Стандартная библиотека C++ содержит последние расширения C++ стандарта ANSI (включая библиотеку стандартных шаблонов и новую библиотеку iostream). Она представляет собой набор файлов заголовков. В новых файлах заголовков отсутствует расширение

H.[1]

Начиная с Visual Studio .NET 2003, Visual C++ больше не предоставляет старые библиотеки iostream

Стандартные заголовочные файлы[

Нижеперечисленные файлы содержат объявления Стандартной Библиотеки.

Контейнеры[править исходный текст]

<bitset>

Реализует специализированный класс контейнеров std::bitset — битовый массив.

<deque>

Реализует шаблон класса контейнера std::deque — двусвязная очередь.

<list>

Реализует шаблон класса контейнера std::list — двусвязный список.

<map>

Реализует шаблоны классов контейнеров std::map и std::multimap — Ассоциативный массив и мультиотображение.

<queue>

Реализует класс адаптер-контейнера std::queue — односторонняя очередь.

<set>

Реализует шаблоны классов контейнеров std::set и std::multiset — сортированные ассоциативные контейнеры или множества.

<stack>

Реализует класс адаптер-контейнера std::stack — стек.

<vector>

Реализует шаблон класса контейнеров std::vector — динамический массив.

Общие[править исходный текст]

<algorithm>

Реализует определения многих алгоритмов для работы с контейнерами.

<functional>

Реализует несколько объект-функций, разработанных для работы со стандартными алгоритмами.

<iterator>

Реализует классы и шаблоны для работы с итераторами.

<locale>

Реализует классы и шаблоны для работы с локалями.

<memory>

Реализует инструменты управления памятью в C++, включая шаблон класса std::auto_ptr.

<stdexcept>

Содержит стандартную обработку ошибок классов, например, std::logic_error и std::runtime_error, причем оба происходят из std::exception.

<utility>

реализует шаблон класса std::pair для работы с парами (двучленными кортежами) объектов.

Строковые[править исходный текст]

<string>

Реализует стандартные строковые классы и шаблоны.

Поточные и ввода-вывода[править исходный текст]

<fstream>

Реализует инструменты для файлового ввода и вывода. Смотри fstream.

<ios>

Реализует несколько типов и функций, составляющих основу операций с iostreams.

<iostream>

Реализует основы ввода и вывода языка C++. Смотри iostream.

<iosfwd>

Реализует предварительные объявления нескольких шаблонов классов, связанных с вводом-выводом.

<iomanip>

Реализует инструменты для работы с форматированием вывода, например базу, используемую при форматировании целых и точных значений чисел с плавающей запятой.

<istream>

Реализует шаблон класса std::istream и других необходимых классов для ввода.

<ostream>

Реализует шаблон класса std::ostream и других необходимых классов для вывода.

<sstream>

Реализует шаблон класса std::sstream и других необходимых классов для работы со строками.

<streambuf>

Числовые[править исходный текст]

<complex>

Реализует шаблон класса std::complex и связанные функции для работы с комплексными числами.

<numeric>

Реализует алгоритмы для числовой обработки

<valarray>

Реализует шаблон класса std::valarray — класс массивов, оптимизированный для числовой обработки.

Языковая поддержка[править исходный текст]

<exception>

Реализует несколько типов и функций, связанных с обработкой исключений, включая std::exception — базовый класс всех перехватов исключений в Стандартной Библиотеке.

<limits>

реализует шаблон класса std::numeric_limits, используемый для описания свойств базовых числовых типов.

<new>

Реализует операторы new и delete, а также другие функции и типы, составляющие основу управления памятью в C++.

<typeinfo>

Реализует инструменты для работы с динамической идентификацией типа данных в C++.

Библиотечные заголовочные файлы ANSI Си[править исходный текст]<assert.h> Содержит макрос утверждений, используемый для обнаружения логических и некоторых других типов ошибок в отлаживаемой версии программы.

<complex.h> Набор функций для работы с комплексными числами. (Появилось в C99)

<ctype.h> Содержит функции, используемые для классификации символов по их типам или для конвертации между верхним и нижним регистрами независимо от используемой кодировки (обычно ASCII или одно из её расширений, хотя есть и реализации, использующие

EBCDIC).

<errno.h> Для проверки кодов ошибок, возвращаемых библиотечными функциями.

<fenv.h> Для управления средой, использующей числа с плавающей точкой. (Появилось в C99)

<float.h> Содержит заранее определенные константы, описывающие специфику реализации свойств библиотеки для работы с числами с плавающей точкой, как, например, минимальная разница между двумя различными числами с плавающей точкой (_EPSILON), максимальное число цифр точности (_DIG) и область допустимых чисел (_MIN, _MAX).

<inttypes.h>

Для точной конвертации целых типов. (Появилось в C99)

<iso646.h>

Для программирования в кодировке ISO 646. (Появилось в NA1)

<limits.h> Содержит заранее заданные константы, определяющие специфику реализации свойств целых типов, как, например, область допустимых значений (_MIN, _MAX).

<locale.h> Для setlocale() и связанных констант. Используется для выбора соответствующего языка.

<math.h> Для вычисления основных математических функций

<setjmp.h>

Объявляет макросы setjmp и longjmp, используемые для нелокальных переходов

<signal.h> Для управления обработкой сигналов

<stdarg.h>Для доступа к различному числу аргументов, переданных функциям.

<stdbool.h>

Для булевых типов данных. (Появилось в C99)

<stdint.h> Для определения различных типов целых чисел. (Появилось в C99)

<stddef.h>Для определения нескольких стандартных типов и макросов.

<stdio.h> Реализует основные возможности ввода и вывода в языке Си. Этот файл содержит весьма важную функцию printf.

<stdlib.h> Для выполнения множества операций, включая конвертацию, генерацию псевдослучайных чисел, выделение памяти, контроль процессов, окружения, сигналов, поиска и сортировки.

<string.h> Для работы с различными видами строк.

<tgmath.h>

Для типовых математических функций. (Появилось в C99)

<time.h> Для конвертации между различными форматами времени и даты.

<wchar.h> Для обработки «широких» потоков и нескольких видов строк при помощи «широких» символов (поддержка набора языков). (Появилось в NA1)

<wctype.h>

Для классификации «широких» символов. (Появилось в NA1)

26.

Структуры в С++ есть совокупность переменных, объединенных под одним именем.

Другими словами можно сказать так.

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

27.

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

Пример на C++[править исходный текст]

union Some {

int i;

double a;

};

Это объединение хранит либо целое число (переменная i), либо число с плавающей точкой (переменная a). Поскольку объединение — это вид структуры, то в C и C++ к нему обращаются так же, как и к структуре: через символ «->» при использовании указателя, или «.» при использовании обычной переменной.

Можно усложнить пример, сделав объединение частью структуры, тогда обращаться надо будет уже через структуру, то есть:

struct STRX {

int j;

Some v, *w;

} a, *b;

Рассмотрим способы обращения к объединению, заданные через указатели, переменные и смешанным образом:

a.v.i=123;

b->v.i=123;

a.w->i=123;

b->w->i=123;

Есть возможность сделать объединение безымянным :

struct STRX {

int j;

union {

int i;

double a;

};

} a;

При этом обращение упрощается:

a.i=123;

a.a=4.5;

28.

6.1. Понятие классов в С++

Идея ООП заключается в описании задачи на уровне объектов, которые в языке С++ называются классами. Например, класс может описывать объект линию, эллипс, прямоугольник. Но в отличие от структур, которые также могут комплексно описывать свойства каких-либо объектов, между классами возможны взаимодействия, которые выражаются тремя категориями: наследование, полиморфизм и инкапсуляция.

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

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

Инкапсуляция – это способ представления класса в виде «черного ящика». Это значит, что конечному пользователю класса (программисту) доступен лишь определенный набор функций и переменных для работы с классом. Часто ограничение доступа применяется для записи значений в переменные класса через функции, при запрещенном непосредственном доступе к переменным.

Класс в языке С++ задается с помощью ключевого слова class, за которым следует его имя и в фигурных скобках {} дается его описание. После определения класса ставится точка с запятой. Ниже приведен пример описания класса для хранения координат графических примитивов:

class CPos

{

int sp_x, sp_y; //координата начала

int ep_x, ep_y; //координата конца

};

Каждый класс имеет специальные функции, которые называются конструктор и деструктор. Конструктор класса вызывается всякий раз, когда объект создается в памяти ЭВМ и служит обычно для инициализации данных класса. Конструктор имеет то же имя, что и имя класса. Деструктор вызывается при удалении класса из памяти и используется, как правило, для освобождения ранее выделенной памяти под какие-либо данные этого класса. Имя деструктора совпадает с именем класса, но перед ним ставится символ ‘~’. Рассмотрим пример реализации конструктора и деструктора для класса CPos.

class CPos

{

public:

CPos() {printf(“Вызов конструктора.\n”);}

~CPos() {printf(“Вызов деструктора.\n”);}

int sp_x, sp_y; //координата начала

int ep_x, ep_y; //координата конца

};

Здесь ключевое слово public используется для обеспечения общего доступа к функциям и переменным класса.

Для создания нового экземпляра класса в памяти ЭВМ используется оператор new языка С++, а для удаления – оператор delete. Использование данных операторов для создания экземпляра класса CPos и его удаления выглядит следующим образом:

CPos *pos_ptr = new CPos(); //создание объекта

delete pos_ptr; //удаление объекта

В результате выполнения этих двух строк программы на экране появятся сообщения:

Вызов конструктора.

Вызов деструктора.

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

CPos pos;

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

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

class CPos

{

public:

CPos(int x1, int y1, int x2,int y2)

{

sp_x = x1; sp_y = y1;

ep_x = x2; ep_y = y2;

}

~CPos() {}

int sp_x, sp_y;

int ep_x, ep_y;

};

и процесс создания экземпляра класса принимает вид:

CPos *pos_ptr = new CPos(10,10,20,20);

или

CPos pos(10,10,20,20);

Такой способ описания и вызова конструктора представляет дополнительное удобство инициализации данных при создании нового объекта. При этом конструктор, как и любую функцию, можно перегружать. Это значит, что можно задать несколько типов конструкторов (с разным набором входных параметров) в одном и том же классе. Например, если создается экземпляр класса графического примитива, но для него неизвестны начальные и конечные координаты, то целесообразно вызвать конструктор CPos() без аргументов, а если координаты известны, то выполнить их инициализацию путем вызова конструктора с аргументами. Для описания нескольких типов конструкторов в одном классе достаточно дать их определения в нем:

class CPos

{

public:

CPos() {}

CPos(int x1, int y1, int x2,int y2)

{

sp_x = x1; sp_y = y1;

ep_x = x2; ep_y = y2;

}

~CPos() {}

int sp_x, sp_y;

int ep_x, ep_y;

};

В классах помимо переменных, конструкторов и деструкторов можно задавать описания и обычных функций, которые, в этом случае, называются методами. Например, в классе CPos для задания значений координат примитива целесообразно добавить функцию для ввода значений в переменные sp_x, sp_y, ep_x и ep_y. Это позволит, во-первых, не запоминать программисту имена этих переменных, а оперировать только одной функцией и, во-вторых, в самой функции можно реализовать необходимые проверки на истинность переданных значений координат перед их присваиванием переменным. Такую функцию можно описать в классе следующим образом:

class CPos

{

public:

CPos() {}

~CPos() {}

void SetParam(int x1, int y1, int x2, int y2)

{

if(x1 >= 0 && x1 <= MAX_SIZE) sp_x = x1;

if(y1 >= 0 && y1 <= MAX_SIZE) sp_y = y1;

if(x2 >= 0 && x2 <= MAX_SIZE) ep_x = x2;

if(y2 >= 0 && y2 <= MAX_SIZE) ep_y = y2;

}

int sp_x, sp_y;

int ep_x, ep_y;

};

В приведенном примере реализована функция SetParam(), которая перед присваиванием значений переменных выполняет проверку на их истинность. Здесь некоторое неудобство представляет то, что данная функция полностью описана в классе CPos, а описание большого числа функций в одном классе делает текст программы трудночитаемым. Поэтому обычно в классах записывают лишь прототипы функций, а их реализации приводят отдельно после описания класса. Для того чтобы описать реализацию функции SetParam() вне класса CPos перед именем функции ставится имя класса с оператором глобального разрешения ‘::’ как показано ниже:

void CPos::SetParam(int x1, int y1, int x2, int y2)

{

if(x1 >= 0 && x1 <= MAX_SIZE) sp_x = x1;

if(y1 >= 0 && y1 <= MAX_SIZE) sp_y = y1;

if(x2 >= 0 && x2 <= MAX_SIZE) ep_x = x2;

if(y2 >= 0 && y2 <= MAX_SIZE) ep_y = y2;

}

а перед ней должно идти следующее определение класса:

class CPos

{

public:

CPos() {}

~CPos() {}

void SetParam(int x1, int y1, int x2, int y2);

int sp_x, sp_y;

int ep_x, ep_y;

};

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

CPos::CPos()

{

//операторы конструктора

}

CPos::~CPos()

{

//операторы деструктора

}

Функцию SetParam() можно вызывать через указатель на класс, используя оператор ‘->’ или через представитель с помощью оператора

‘.’:

CPos* pos_ptr = new CPos();

CPos pos;

pos_ptr->SetParam(10,10,20,20);

pos.SetParam(10,10,20,20);

Таким же образом можно обращаться и к переменным класса:

pos_ptr->sp_x = 10;

pos.sp_x = 20;

Здесь можно заметить, что значения переменных sp_x, sp_y, ep_x и ep_y могут быть заданы как непосредственно при обращении к ним, так и с помощью функции SetParam(). В результате проверка, реализованная в данной функции, может быть проигнорирована программистом. Часто такая ситуация недопустима, например, при использовании готовых классов библиотек MFC, VCL, OWL и др. В связи с этим в классах для переменных и функций предусмотрена возможность установки разных уровней доступа, которые определяются тремя ключевыми словами: public, private и protected.

Ключевое слово public означает общий доступ к переменным и функциям класса. Уровень доступа private указывает на частный способ доступа к элементам класса и устанавливается по умолчанию при описании класса. Частный уровень доступа дает возможность обращаться к переменным и функциям только внутри класса и запрещает извне, например, через представители или указатели на класс. Режим доступа protected также как и private запрещает доступ к элементам класса через представители и указатели, но разрешает обращаться к ним из дочерних классов при наследовании.

Учитывая эти три режима доступа, класс для работы с координатами графических объектов целесообразно записать в таком виде:

class CPos

{

public:

CPos() {}

~CPos() {}

void SetParam(int x1, int y1, int x2, int y2);

private:

int sp_x, sp_y;

int ep_x, ep_y;

};

Здесь раздел private ограничивает доступ пользователю класса к переменным sp_x, sp_y, ep_x и ep_y только функцией SetParam(). Следует также отметить, что отсутствие раздела public вначале описания класса привело бы к тому, что все функции класса CPos имели бы область видимости private. В результате доступ к конструктору и деструктору был бы запрещен, и создание нового объекта стало бы невозможным. Аналогичная картина имеет место и в режиме доступа protected, но в отличие от private класс можно использовать как базовый в механизме наследования. Это свойство полезно использовать для запрета создания экземпляров класса, что бывает необходимым, если он является лишь промежуточным звеном в иерархии объектов и не представляет ценности как отдельный объект.

28.

Класс — разновидность абстрактного типа данных в объектно-ориентированном программировании (ООП), характеризуемый способом своего построения. Другие абстрактные типы данных — метаклассы, интерфейсы, структуры, перечисления, — характеризуются какими-то своими, другими особенностями. Наряду с понятием «объекта» класс является ключевым понятием в ООП (хотя существуют и бесклассовые объектно-ориентированные языки, например, Self, Lua; подробнее смотрите Прототипное программирование). Суть отличия классов от других абстрактных типов данных состоит в том, что при задании типа данных класс определяет одновременно и интерфейс, и реализацию для всех своих экземпляров, а вызов метода-конструктора обязателен. Точный смысл этой фразы будет раскрыт ниже.

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