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

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

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

1. Понятие архитектуры ЭВМ

С середины 60-х годов существенно изменился подход к созданию вычислительных машин. Вместо независимой разработки аппаратуры и некоторых средств математического обеспечения стала проектироваться система, состоящая из совокупности аппаратных (hardware) и программных (software) средств. При этом на первый план выдвинулась концепция их взаимодействия. Так возникло принципиально новое понятие — архитектура ЭВМ. программирование вычислительный техника

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

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

Рис. 1. Основные компоненты архитектуры ЭВМ

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

Так, пользователю ЭВМ безразлично, на каких элементах выполнены электронные схемы, схемно или программно реализуются команды и т.д. Важно другое: как те или иные структурные особенности ЭВМ связаны с возможностями, предоставляемыми пользователю, какие альтернативы реализованы при создании машины и по каким критериям принимались решения, как связаны между собой характеристики отдельных устройств, входящих в состав ЭВМ, и какое влияние они оказывают на общие характеристики машины. Иными словами, архитектура ЭВМ действительно отражает круг проблем, относящихся к общему проектированию и построению вычислительных машин и их программного обеспечения.

Структура и принципы функционирования ЭВМ

Более чем за полвека развития вычислительных средств прогресс в аппаратной реализации ЭВМ и их технических характеристик превзошел все прогнозы, и пока не заметно снижение его темпов. Несмотря на то, что современные ЭВМ внешне не имеют ничего

общего с первыми моделями, основополагающие идеи, заложенные в них и связанные с понятием алгоритма, разработанным Аланом Тьюрингом, а также архитектурной

реализацией, предложенной Джоном фон Нейманом, пока не претерпели коренных изменений (за исключением систем параллельной обработки информации).

Любая ЭВМ неймановской архитектуры содержит следующие основные устройства:

-арифметико-логическое устройство (АЛУ);

-устройство управления (УУ);

-запоминающее устройство (ЗУ);

-устройства ввода-вывода (УВВ);

-пульт управления (ПУ).

В современных ЭВМ АЛУ и УУ объединены в общее устройство, называемое центральным процессором. Обобщенная логическая структура ЭВМ представлена на рис. 2.

Рис. 2. Обобщенная логическая структура ЭВМ

Процессор, или микропроцессор, является основным устройством ЭВМ. Он предназначен для выполнения вычислений по хранящейся в запоминающем устройстве программе и обеспечения общего управления ЭВМ. Быстродействие ЭВМ в значительной мере определяется скоростью работы процессора. Для ее увеличения процессор использует собственную память небольшого объема, именуемую местной или сверхоперативной, что в некоторых случаях исключает необходимость обращения к запоминающему устройству ЭВМ.

Вычислительный процесс должен быть предварительно представлен для ЭВМ в виде программы - последовательности инструкций (команд), записанных в порядке выполнения. В процессе выполнения программы ЭВМ выбирает очередную команду, расшифровывает ее, определяет, какие действия и над какими операндами следует выполнить. Эту функцию осуществляет УУ. Оно же помещает выбранные из ЗУ операнды в АЛУ, где они и обрабатываются. Само АЛУ работает под управлением УУ.

Обрабатываемые данные и выполняемая Программа должны находиться в запоминающем устройстве - памяти ЭВМ, куда они вводятся через устройство ввода. Емкость памяти измеряется в величинах, кратных байту. Память представляет собой сложную структуру, построенную по иерархическому принципу, и включает в себя запоминающие устройства различных типов. Функционально она делится на две части: внутреннюю и внешнюю.

Внутренняя, или основная память — это запоминающее устройство, напрямую связанное с процессором и предназначенное для хранений выполняемых программ и данных, непосредственно участвующих в вычислениях. Обращение к внутренней памяти ЭВМ осуществляется с высоким быстродействием, но она имеет ограниченный объем, определяемый системой адресации машины.

Внутренняя память, в свою очередь, делится на оперативную (ОЗУ) и постоянную (ПЗУ) память. Оперативная память, по объему составляющая большую часть внутренней памяти, служит для приема, хранения и выдачи информации. При выключении питания ЭВМ содержимое оперативной памяти в большинстве случаев теряется. Постоянная память обеспечивает хранение и выдачу информации. В отличие от содержимого оперативной памяти, содержимое постоянной заполняется при изготовлении ЭВМ и не может быть изменено в обычных условиях эксплуатации. В постоянной памяти хранятся часто используемые (универсальные) программы, и данные; к примеру, некоторые программы операционной системы, программы тестирования оборудования ЭВМ и др. При выключении питания содержимое постоянной памяти сохраняется.

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

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

ВЗУ по принципам функционирования разделяются на устройства прямого доступа (накопители на магнитных и оптических дисках) и устройства последовательного доступа (накопители на магнитных лентах). Устройства прямого доступа обладают большим быстродействием, поэтому они являются основными внешними запоминающими устройствами, постоянно используемыми в процессе функционирования ЭВМ. Устройства последовательного доступа используются в основном для резервирования информации.

Устройства ввода-вывода служат соответственно для ввода информации в ЭВМ и вывода из нее, а также для обеспечения общения пользователя с машиной. Процессы ввода-вывода протекают с использованием внутренней памяти ЭВМ. Иногда устройства вводавывода называют периферийными или внешними устройствами ЭВМ. К ним относятся, в частности, дисплеи (мониторы), клавиатура, манипуляторы типа «мышь», алфавитно-цифровые печатающие устройства (принтеры), графопостроители, сканеры и др. Для управления внешними устройствами (в том числе и ВЗУ) и согласования их с системным интерфейсом служат групповые устройства управления внешними устройствами, адаптеры или контроллеры.

Системный интерфейс - это конструктивная часть ЭВМ, предназначенная для взаимодействия ее устройств и обмена информацией между ними.

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

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

Пульт управления служит для выполнения оператором ЭВМ или системным программистом системных операций в ходе управления вычислительным процессом. Кроме того, при техническом обслуживании ЭВМ за пультом управления работает инженернотехнический персонал. Пульт управления конструктивно часто выполняется вместе с центральным процессором.

Система счисления (нумерация лат. numeratio) — метод обозначения чисел посредством знаков — цифр, или слов. Система обозначения, основанная на цифрах — письменная нумерация. Система обозначения, основанная на словах — словесная нумерация.

Системы счисления разделяют на позиционные и непозиционные. Различие позиционных систем счисления от непозиционных состоит в том, что значение цифр в позиционной системе зависит от позиции в числе, а в непозиционной — не зависит. Примеры позиционных систем счисления: десятичная система счисления, основанная на арабских цифрах; древневавилонянская (60-ричная); система Майя (20-ричная). Примеры непозиционных систем счисления — римская, старая и новая греческая, славянская.

Позиционные и многие непозиционные системы счисления имеют так называемое основание. Основание также определяет деления чисел на порядки. Числа, меньшие основания, называются числами первого порядка, до второй степени основания (n·n) — числами второго и так далее. Числа соотносящиеся на основание считаются различающимися на один порядок.

Системы счисления, обладающие основанием имеют регулярную структуру названий — числа, отличающиеся на порядок, образуются подобным образом. Для позиционных систем счисления основание означает, во сколько раз изменится значение цифры смещении на одну позицию — 3 и 30 в десятичной системе отличаются в десять раз. Непозиционные системы счисления обычно включают знаки для чисел, меньших основания и и помноженных на целую степень основания, например римская — I=1, V=5, X=10, L=50, C=100 — цифры I к X и к C, относятся как основание системы счисления, аналогично относятся V и L.

Системы счисления также различающиеся тем, как образуются числа внутри порядка. Один очевидный способ образования — повторение символа единицы необходимое количество раз — он используется во многих древних системах — египетской, вавилонянской, старой греческой, римской и других. Такой подход обеспечивает использование достаточно малое количество различных симоволов, но является весьма расточительным. Нередким в таких системах было использование дополнительного основания, меньшего основного. Числа, одного порядка формировались аналогично с использованием дополнительного основания. Это позволяло значительно сократить количество повторений. Дополнительными основаниями часто служили 5 и 10. Так, отдельный символ для обозначения 5 есть в старой греческой и римской нумерации — Γ и V, а также у майя. 5 в качестве промежуточного основания связан со счётом по пальцам, и обозначал, что закончились пальцы на руке (или ноге). Промежуточное основание 10 использовалось в древневавилонской клинописной 60-чной системе счисления.

Другой способ, использовавшийся в более новых — использование различных символов. Такой подход используется широко используемой десятичной системе счисления — цифры 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Такой же подход применялся в новогреческой и заимствованной от неё древнерусской. В них в качестве цифр использовались буквы — в новой греческой это греческий алфавит, в древнерусской — кириллица или глаголица, причём цифровые значения букв кириллица полностью соответствовали таковым в греческом, у глаголицы отличались. Эти системы использовали 27 букв со значениями: от 1 до 9 через один, 10 по 90 через десяток, 100 по 900 — через сотню.

2. Понятие алгоритма — одно из основных в программировании и информатике[1]. Это последовательность команд, предназначенная исполнителю, в результате выполнения которой он должен решить поставленную задачу. Алгоритм должен описываться на формальном языке, исключающем неоднозначность толкования. Исполнитель может быть человеком или машиной. Исполнитель должен уметь выполнять все команды, составляющие алгоритм. Множество возможных команд конечно и изначально строго задано. Действия, выполняемые по этим командам, называются элементарными.

Запись алгоритма на формальном языке называется программой. Иногда само понятие алгоритма отождествляется с его записью, так что слова «алгоритм» и «программа» — почти синонимы. Небольшое различие заключается в том, что под алгоритмом, как правило, понимают основную идею его построения. Программа же всегда связана с записью алгоритма на конкретном формальном языке.

Схема — графическое представление определения, анализа или метода решения задачи, в котором используются символы для отображения данных, потока, оборудования и т. д.[1]

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

3,4. C++ — компилируемый статически типизированный язык программирования общего назначения.

Поддерживает такие парадигмы программирования как процедурное программирование, объектно-ориентированное программирование, обобщённое программирование, обеспечивает модульность, раздельную компиляцию, обработку исключений, абстракцию данных, объявление типов (классов) объектов, виртуальные функции. Стандартная библиотека включает, в том числе, общеупотребительные контейнеры и алгоритмы. C++ сочетает свойства как высокоуровневых, так и низкоуровневых языков[1]. В сравнении с его предшественником — языком C, — наибольшее внимание уделено поддержке объектно-ориентированного и обобщённого программирования[2].

Синтаксис C++ унаследован от языка C. Одним из принципов разработки было сохранение совместимости с C. Тем не менее, C++ не является в строгом смысле надмножеством C; множество программ, которые могут одинаково успешно транслироваться как компиляторами C, так и компиляторами C++, довольно велико, но не включает все возможные программы на C.

Состав:

Стандартная библиотека включает в себя следующие разделы:

Поддержка языка. Включает средства, которые необходимы для работы программ, а также сведения об особенностях реализации. Выделение памяти, RTTI, базовые исключения, пределы значений для числовых типов данных, базовые средства взаимодействия со средой, такие как системные часы, обработка сигналов UNIX, завершение программы.

Стандартные контейнеры. В стандартную библиотеку входят шаблоны для следующих контейнеров: одномерные массивы, списки, одно- и двунаправленные очереди, стеки, ассоциативные массивы, множества, очереди с приоритетом.

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

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

Алгоритмы. Шаблоны для описания операций обработки, которые с помощью механизмов стандартной библиотеки могут применяться к любой последовательности элементов, в том числе к элементам в контейнерах. Также в этот раздел входят описания функций bsearch() и qsort() из стандартной библиотеки C.

Строки. Шаблоны строк в стиле C++. Также в этот раздел попадает часть библиотек для работы со строками и символами в стиле C.

Ввод-вывод. Шаблоны и вспомогательные классы для потоков ввода-вывода общего вида, строкового ввода-вывода, манипуляторы (средства управления форматом потокового ввода-вывода в стиле C++).

Локализация. Определения, используемые для поддержки национальных особенностей и форматов представления (дат, валют и т. д.) в стиле C++ и в стиле C.

Диагностика. Определения ряда исключений и механизмов проверки утверждений во время выполнения (assert). Поддержка обработки ошибок в стиле C.

Числа. Определения для работы с комплексными числами, математическими векторами, поддержка общих математических функций, генератор случайных чисел.

Контейнеры, строки, алгоритмы, итераторы и основные утилиты, за исключением заимствований из библиотеки C, собирательно называются STL (Stanard Template Library — стандартная шаблонная библиотека). Изначально эта библиотека была отдельным продуктом и её аббревиатура расшифровывалась иначе, но потом она вошла в стандартную библиотеку C++ в качестве неотъемлемого элемента. В названии отражено то, что для реализации средств общего вида (контейнеров, строк, алгоритмов) использованы механизмы обобщённого программирования (шаблоны C++ — template). В работах Страуструпа подробно описываются причины, по которым был сделан именно такой выбор. Основными из них являются большая универсальность выбранного решения (шаблонные контейнеры, в отличие от объектных, могут легко использоваться для не объектных типов и не требуют наличия общего предка у типов элементов) и его техническая эффективность (как правило, операции шаблонного контейнера не требуют вызовов виртуальных функций и могут легко встраиваться (inline), что в итоге даёт столь же производительный код, как и при ручном кодировании).

Стандарт C++ на 2003 год состоит из двух основных частей: описание ядра языка и описание стандартной библиотеки.

Кроме того, существует огромное количество библиотек C++, не входящих в стандарт. В программах на C++ можно использовать многие библиотеки C.

Стандартизация определила язык программирования C++, однако за этим названием могут скрываться также неполные, ограниченные, достандартные варианты языка. Первое время язык развивался вне формальных рамок, спонтанно, по мере встававших перед ним задач. Развитию языка сопутствовало развитие кросс-компилятора cfront. Новшества в языке отражались в изменении номера версии кросс-компилятора. Эти номера версий кросс-компилятора распространялись и на сам язык, но применительно к настоящему времени речь о версиях языка C++ не ведут.

Необъектно-ориентированные возможности[править исходный текст]

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

Комментарии

С++ поддерживает как комментарии в стиле C:

/*

это комментарий, который может состоять

из нескольких строчек

*/

так и однострочные:

// вся оставшаяся часть строки является комментарием

где // обозначает начало комментария, а ближайший последующий символ новой строки, который не предварён символом \ (либо эквивалентным ему обозначением ??/), считается окончанием комментария.

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

В C++ доступны следующие встроенные типы:

Символьные: char, wchar_t (char16_t и char32_t, в стандарте C++11).

Целочисленные знаковые: signed char, short int, int, long int (и long long int, в стандарте C++11).

Целочисленные беззнаковые: unsigned char, unsigned short int, unsigned int, unsigned long int(и unsigned long long int, в стандарте C++11).

С плавающей точкой: float, double, long double.

Логический: bool, имеющий значения true и false.

Операции сравнения возвращают тип bool. Выражения в скобках после if, while приводятся к типу bool.[9]

Функции могут принимать аргументы по ссылке. Например, функция void f(int &x) {x=3;} присваивает своему аргументу значение 3. Функции также могут возвращать результат по ссылке, и ссылки могут быть вне всякой связи с функциями. Например, {double &b=a[3]; b=sin(b);} эквивалентно a[3]=sin(a[3]);. При программировании ссылки в определённой степени сходны с указателями, со следующими особенностями: перед использованием ссылка должна быть инициализирована; ссылка пожизненно указывает на один и тот же адрес; в выражении ссылка обозначает непосредственно тот объект или ту функцию, на которую она указывает, обращение же к объекту или функции через указатель требует разыменование указателя. Существуют и другие отличия в использовании указателей и ссылок. Концептуально ссылка — другое имя переменной или функции, другое название одного и того же адреса, существует лишь только в тексте программы, заменяемое адресом при компиляции; а указатель — переменная, хранящая адрес, к которому обращаются.

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

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

inline double Sqr(double x) {return x*x;}.

Описатель volatile используется в описании переменных и информирует компилятор, что значение данной переменной может быть изменено способом, который компилятор не в состоянии отследить. Для переменных, объявленных volatile, компилятор не должен применять средства оптимизации, изменяющие положение переменной в памяти (например, помещающие её в регистр) или полагающиеся на неизменность значения переменной в промежутке между двумя присваиваниями ей значения. В мультиядерной системе volatile помогает избегать барьеров памяти 2-го типа[источник не указан 364 дня].

Если описана структура, класс, объединение (union) или перечисление (enum), её имя является именем типа, например:

struct Time {

int hh, mm, ss;

};

Time t1, t2;

Добавлены пространства имён (namespace). Например, если написать

namespace Foo

{

const int x=5;

typedef int** T;

void f(int y) {return y*x};

double g(T);

...

}

то вне фигурных скобок следует обращаться к T, x, f, g как Foo::T, Foo::x, Foo::f и Foo::g соответственно. Если в каком-то файле нужно обратиться к ним непосредственно, можно написать

using namespace Foo;

Или же

using Foo::T;

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

namespace

{

...

}

Все имена, описанные в нём, доступны в текущей единице трансляции и больше нигде.

Один или несколько последних аргументов функции могут задаваться по умолчанию. К примеру, если функция описана как void f(int x, int y=5, int z=10), вызовы f(1), f(1,5) и f(1,5,10) эквивалентны.

При описании функций отсутствие аргументов в скобках означает, в отличие от C, что аргументов нет, а не то, что они неизвестны. Если аргументы неизвестны, надо пользоваться многоточием, например, int printf(const char* fmt, ...).

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

struct S

{

typedef int** T;

T x;

};

S::T y;

Могут быть несколько функций с одним и тем же именем, но разными типами или количеством аргументов (перегрузка функций; при этом тип возвращаемого значения на перегрузку не влияет). Например, вполне можно писать:

void Print(int x);

void Print(double x);

void Print(int x, int y);

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

struct Date {int day, month, year;};

void operator ++(struct Date& date);

Операторные функции во многом схожи с обычными (неоператорными) функциями. За исключением операторов new, new[], delete и delete[], нельзя переопределять поведение операторов для встроенных типов (скажем, переопределять умножение значений типа int); нельзя создавать новые операторы, которых нет в C++ (скажем, **); нельзя менять количество операндов, предусмотренное для оператора, а также нельзя менять существующие приоритеты и ассоциативность операторов (скажем, в выражении a+b*c сначала будет выполняться умножение, а потом сложение, к каким бы типам ни принадлежали a, b и c). Можно переопределить операции [] (с одним параметром) и () (с любым числом параметров).

Добавлены шаблоны (template). Например, template<class T> T Min(T x, T y) {return x<y?x:y;} определяет функцию Min для любых типов.

Шаблоны могут задавать не только функции, но и типы. Например, template<class T> struct Array{int len; T* val;}; определяет массив значений любого типа, после чего мы можем писать Array<float> x;

В дополнение к функциям malloc и free введены операторные функции operator new, operator new[], operator delete и operator delete[],

а также операторы new, new[], delete и delete[]. Если T — произвольный объектный тип, не являющийся типом массива, X — произвольный объектный тип и A — тип массива из некоторого количества n элементов, имеющих тип X, то

new T выделяет память (посредством вызова функции operator new), достаточную для размещения одного объекта типа Т, возможно, инициализирует объект в этой памяти, и возвращает указатель типа Т* (например, Т* p = new T).

new X[n] и new A выделяют память (посредством вызова функции operator new[]), достаточную для размещения n объектов типа X, возможно, инициализируют каждый объект в этой памяти, и возвращают указатель типа X* (например, X* p = new X[n]).

delete p — разрушает объект (не являющийся массивом), на который ссылается указатель p, и освобождает область памяти (посредством вызова функции operator delete), ранее выделенную для него new-выражением.

delete [] p — разрушает каждый объект в массиве, на который ссылается указатель p, и освобождает область памяти (посредством вызова функции operator delete[]), ранее выделенную для этого массива new-выражением.

Операция delete проверяет, что её аргумент не является нулевым указателем, в противном случае она ничего не делает. Для инициализации объекта non-POD классового типа new-выражение вызывает конструктор; для уничтожения объекта классового типа delete-выражение вызывает деструктор (см. ниже).

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

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

В стандарте C++ под классом (class) подразумевается пользовательский тип, объявленный с использованием одного из ключевых слов class, struct или union, под структурой (structure) подразумевается класс, определённый через ключевое слово struct, и под объединением (union) подразумевается класс, определённый через ключевое слово union.

Описание функций в теле класса[править исходный текст]

В теле класса можно указать только заголовок функции, а можно описать всю функцию (см. пример с функцией Alloc ниже. В этом случае она считается встраиваемой (inline))

Константные функции-члены[править исходный текст]

Нестатические функции-члены (и только они) могут иметь описатель const

class Array

{

...

inline double operator[] (int n) const;

Такие функции не имеют права изменять поля класса (кроме полей, определённых как mutable). Если они пытаются это сделать, компилятор должен выдать сообщение об ошибке.

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

В C++ при наследовании одного класса от другого наследуется реализация класса, плюс класс-наследник может добавлять свои поля и функции или переопределять функции базового класса. Множественное наследование разрешено.

Конструктор наследника вызывает конструкторы базовых классов, а затем конструкторы нестатических членов-данных, являющихся экземплярами классов. Деструктор работает в обратном порядке.

Наследование бывает публичным, защищённым и закрытым (то есть закрытого типа):Доступ члена базового класса/режим

наследования

private-член

protected-член

public-член

private-наследование

недоступен

private

private

protected-наследование

недоступен

protected protected

public-наследованиенедоступен

protected

public

 

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

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

Семантика системы типов С++ не полиморфна (в отличие от потомков ML, в том числе гибридных с Си — BitC, Cyclone), однако есть несколько способов обеспечить полиморфное поведение. Прежде всего это перегрузка методов классов при наследовании — традиционный для ООП способ обеспечения абстракции данных. Затем есть два способа реализации параметрического полиморфизма (в С++-сообществе обычно называемого «обобщённым программированием»). Первый способ унаследован из Си — использование бестипового указателя и приведение типа в зависимости от других данных — хотя в С++ этот способ традиционно считается неидеоматичным и опасным. Второй заключается в использовании шаблонов — но, в отличие от обычных реализаций параметрического полиморфизма, в С++ происходит автоматическая генерация семейства перегруженных мономорфных функций на

основании полиморфного определения (шаблона) в соответствии с контекстами его использования — то есть параметрический полиморфизм на уровне исходного кода транслируется в ситуативный (ad hoc) на уровне машинного, за что С++ подвергается критике (см. раздел Вычислительная производительность). В С++ также есть третий вид перегрузки — перегрузка операторов — которая в сочетании с наследованием классов предоставляет ещё большие возможности повышения читабельности кода путём ввода т. н. «синтаксического сахара».

Для обеспечения абстракции данных необходимо связать несколько классов в иерархию наследования и назначить функциям одинаковые спецификации. Например:

class Figure

{

...

void Draw() const;

...

};

class Square : public Figure

{

...

void Draw() const;

...

};

class Circle : public Figure

{

...

void Draw() const;

...

};

class Window

{

...

void Draw() const;

...

};

class SquareWindow : public Window

{

...

void Draw() const;

...

};

class RoundWindow : public Window

{

...

void Draw() const;

...

};

В результате компиляции этих определений формируется шесть тел функций. В коде они используются одинаково; выбор конкретного экземляра функции осуществляется в зависимости от типа экземпляра объекта, для которого осуществляется вызов. Согласованность поведения функций остаётся на совести программиста.

Circle *c = new Circle(0,0,5);

Figure *f = c; // правильно: Figure — базовый класс для Circle

c->Draw();

f->Draw(); // Указатели равны друг другу, но для f и c будут вызваны разные функции

SquareWindow *sw = new SquareWindow(0,0,5);

sw->Draw(); // используется так же

f = sw; // ошибка! SquareWindow не входит в число наследников Figure!

Как видно, диапазон этого вида полиморфизма в С++ ограничивается на этапе проектирования заданным перечнем типов. По умолчанию такой полиморфизм является статическим, но при использовании спецификатора virtual он превращается в динамический (см. позднее связывание):

class Figure

{

...

virtual void Draw() const;

...

};

class Square : public Figure

{

...

void Draw() const;

...

};

class Circle : public Figure