
2 семестр ФИБС / Информатика / Билеты
.docx
ООП. Понятие объекта. Характеристики ООП. ООП ( объектно-ориентированное программирование) представляет собой способ организации кода программы, когда основными строительными блоками программы являются объекты и классы, а логика работы программы построена на их взаимодействии. Объект – переменная типа класс, имеющая свои свойства и методы./
Понятие класса в С++. Характерные элементы класса. Объявление класса и создание объектов класса. Класс –это новый тип данных с доступом к данным, разрешённым только определённому множеству функций. Класс, как и структура1, представляет собой набор данных и функций, предназначенных для совместного выполнения определённой задачи. Характерные элементы класса:1. средства контроля доступа;2. конструкторы;3. деструкторы;4. элементы–данные;5. функции–члены;6. специально скрытый указатель this.
Функции-члены класса. Описание и вызов. Подставляемые функции. Функции-члены реализуют набор операций, применимых к объектам класса. Описание функции–члена класса осуществляется при помощи операции принадлежности::, которая определяет, к какому классу относится эта функция. На практике объявление класса (создание шаблона) и описание функции–членов, как правило, осуществляется до main, так какне требует выделения памяти. Подставляемые или встраиваемые (inline) функции – это функции, код которых вставляется компилятором непосредственно на место вызова, вместо передачи управления единственному экземпляру функции. Если функция является подставляемой, компилятор не создает данную функцию в памяти, а копирует ее строки непосредственно в код программы по месту вызова. Это равносильно вписыванию в программе соответствующих блоков вместо вызовов функций. Таким образом, спецификатор inline определяет для функции так называемое внутреннее связывание, которое заключается в том, что компилятор вместо вызова функции подставляет команды ее кода. Подставляемые функции используют, если тело функции состоит из нескольких операторов.
Создание объекта класса. Доступ к компонентам класса. Уточнение имени элемента. Объекты класса создаются и инициализируются специальными функциями, называемыми конструкторами. Существует несколько уровней доступа к компонентам класса. Рассмотрим два основных.
public
- члены класса открыты для доступа извне.
private
- члены класса закрыты для доступа извне.
protected
-защищённые используется когда есть
наследование По умолчанию все переменные
и функции, принадлежащие классу,
определены как закрытые (private).
Это означает, что они могут использоваться
только внутри функций-членов самого
класса. Для других частей программы,
таких как функция main(), доступ к закрытым
членам запрещен. Это, кстати, единственное
отличие класса от структуры - в структуре
все члены по умолчанию - public.
Для
идентификации функции как члена
некоторого класса требуется специальный
синтаксис объявления: имя функции должно
быть квалифицировано именем ее класса.
( типданных имякласса::имяфункции(тип
переменной переменная…);
Конструкторы. Значения параметров по умолчанию. Перегрузка конструкторов. Конструктор–специальная функция, являющаяся членом класса и имеющая тоже имя, что и класс. Для конструктора не указывается тип возвращаемого значения. Конструкторы обычно используются для инициализации переменных-членов класса значениями. Параметр по умолчанию (или ещё «необязательный параметр») — это параметр функции, который имеет определённое (по умолчанию) значение. Если пользователь не передаёт в функцию значение для параметра по умолчанию, то используется значение по умолчанию. Если же пользователь передаёт значение, то это значение используется вместо значения по умолчанию.
Перегруженный конструктор это такой
как обычный, но будет отличаться
параметрами и одинаковым названием.
Деструкторы, явный и неявный вызов. Типы создаваемых объектов. Массивы объектов. Деструкторы –это специальные функции-члены, которые уничтожают объекты класса и освобождают занимаемую этими объектами память; также осуществляют восстановление экрана, закрытие файла и т.д. Деструктор имеет такое же имя, как и класс, но перед ним ставится знак тильда ~.Деструктор не должен иметь ни параметров, ни типа возвращаемого значения. Деструктор вызывается явно или не явно. Явно –при уничтожении объекта. Не явно –для локальных объектов, когда перестаёт быть активным блок, в котором данный объект объявлен. Массивы объектов создаются так же, как массивы элементов, поэтому можно создавать многомерные массивы объектов. При создании массивов объекта в классе обязательно должен присутствовать конструктор, имеющий все параметры по умолчанию, конструктор без параметров, или, или вообще конструктора может не быть.
Дружественные функции. Дружественные классы. Дружественная функция — это функция, которая имеет доступ к закрытым членам класса, как если бы она сама была членом этого класса. Во всех других отношениях дружественная функция является обычной функцией. Ею может быть как обычная функция, так и метод другого класса. Для объявления дружественной функции используется ключевое слово friend перед прототипом функции, которую вы хотите сделать дружественной классу. Неважно, объявляете ли вы её в public или в private зоне класса. Один класс можно сделать дружественным другому классу. Это откроет всем членам первого класса доступ к закрытым членам второго класса.
Структуры, объединения и классы. Статические элементы класса. Структура - это совокупность переменных, объединенных одним именем, предоставляющая общепринятый способ совместного хранения информации. Объявление структуры приводит к образованию шаблона, используемого для создания объектов структуры. Переменные, образующие структуру, называются членами структуры. struct addr { char name[30]; char street [40]; char city[20]; char state[3]; unsigned long int zip; }; Единственным отличием между структурой и классом является то, что члены класса, по умолчанию, являются закрытыми, а члены структуры — открытыми. Объединение – это группирование переменных, которые разделяют одну и ту же область памяти. В зависимости от интерпретации осуществляется обращение к той или другой переменной объединения. Все переменные, что включены в объединение начинаются с одной границы. Объединение позволяет представить в компактном виде данные, которые могут изменяться. Одни и те же данные могут быть представлены разными способами с помощью объединений.
C++ позволяет определять переменные и методы, которые относятся непосредственно к классу или иначе говоя статические члены класса. Статические переменные и методы относят в целом ко всему классу. Для их определения используется ключевое слово static. В функции можно объявить статические переменные : такие переменные не будут удалены после конца первого вызова функции и будут доступны всем следующим вызовам. Они имеют статическую продолжительность хранения (они существуют с самого начала программы до конца), не привязаны к конкретному экземпляру класса, и для всего класса существует только одна копия.
Перегруженные функции. Выбор экземпляра функции. Перегрузка конструкторов. Возможность создания перегруженных функций в С++ является одним из способов реализации полиморфизма. Две или более функций могут иметь одно и тоже имя и отличаться количеством или типом параметров. Обычно перегруженные функции используются для реализации похожих действий над данными разного типа. При выборе требуемого экземпляра функции осуществляется сравнение типов и числа параметров и аргументов: –параметры –формальные параметры функции, –аргументы –реальные значения при вызове функций. Существует три возможных варианта: 1. точное соответствие типов аргументов параметрам одного из экземпляров функции. 2. соответствие аргументов параметрам может быть достигнуто путём преобразования типов аргументов к типам параметров только для одного экземпляра функции. В этом случае компилятор пытается сначала выполнить стандартные преобразования, которые определены пользователем. 3. соответствие может быть достигнуто более чем для одного экземпляра функции. При этом необходимо иметь ввиду, что преобразование типов, определённое пользователем, имеет меньший приоритет по сравнению со стандартным преобразованием. Если соответствие типов достигается путём равноправных преобразований, компилятор выдаёт сообщение об ошибке: «невозможно определить однозначно экземпляр функции». Хотя конструкторы и предназначены для решения особо важных задач, они мало чем отличаются от обычных функций и могут быть перегружены.
Динамическое выделение памяти. Динамическая инициализация объектов и локальные переменные. Оператор new выделяет соответствующее место для переменной в соответствующей области памяти и возвращает адрес выделенного места, в случае успеха и NULL, если ошибка. Оператор new сам определяет размер типа type_varи возвращает указатель, преобразованный к этому типу. Пример на структоре. Data – имя структоры, а tomas – объект, struct data *tomas; tomas = (struct data*)malloc(n*sizeof(struct data)); delete tomas; Пример на классе: vector::vector(int n) // конструктор { N=n; (кол-во) mas=new int[n]; } Динамически можно выделить память под объект любого определённого к этому моменту типа. Динамическое выделение памяти под одиночные переменные не выгодно, так как расходуется память и под саму информацию о её выделении. Целесообразно динамически выделять память под массивы больших размеров или под массивы, размерность которых определяется в процессе выполнения программы. Это обычно делается в конструкторе класса.
Наследование. Виды наследования. Управление доступом производных классов.
Наследование –это одна из важных черт языков объектно-ориентированного программирования. Наследование реализуется
возможностью
объединять один класс другим во время
объявления второго класса. Механизм
наследования позволяет определять
новые классы, на основе уже имеющихся.
Класс, на основе
которого создаётся новый класс, называется
базовым (родительским классом), а новый
–производным (или наследником).
Непосредственно базовым классом
называется такой класс, который входит
в список базовых классов при определении
класса. Любой
производный класс может стать базовым
для других создаваемых классов, таким
образом реализуется иерархия классов
и объектов.
(Управление
доступа в 5 лекции 10.2.)
При
наследовании некоторые имена методов
(функций-членов) и полей (данных-членов)
базового класса могут быть по-новому
определены в производном классе. В этом
случае соответствующие компоненты
базового класса становятся недоступными
из производного класса. Для доступа из
производного класса к компонентам
базового класса, имена которых повторно
определены в производном, используется
операция разрешения контекста ::
Для
порождения нового класса на основе
существующего используется следующая
общая форма :
сlass Имя : МодификаторДоступа ИмяБазовогоКласса { объявление_членов;};
При объявлении порождаемого класса
Модификатор Доступа может принимать
значения public, private, protected либо отсутствовать,
по умолчанию используется значение
private. В любом случае порожденный класс
наследует все члены базового класса,
но доступ имеет не ко всем. Ему доступны
общие (public) члены базового класса и
недоступны частные (private). Для того, чтобы
порожденный класс имел доступ к некоторым
скрытым членам базового класса, в базовом
классе их необходимо объявить со
спецификацией доступа защищенные
(protected).
Одиночное и множественное наследование.
Конструкторы и деструкторы при наследовании. Конструктора с параметрами. Конструктора и деструкторы:
Пока конструкторы базовых классов не имеют аргументов, производный класс может не иметь функцию конструктор. Если же конструктор базового класса имеет один или несколько аргументов, каждый производный класс обязан иметь конструктор. Чтобы передать аргументы в базовый класс нужно объявить их после объявления конструктора базового класса. Синтаксис: Конструктор производного класса (список аргументов.): базовый класс1 (список аргументов),...Базовый класс п. ((список аргументов.) {...} Список аргументов, ассоциированных с базовым классом, может состоять из констант, глобальных переменных или параметров для конструктора производного класса. Так как объект инициализируется во время выполнения программы можно в качестве параметров использовать переменные.
Массивы объектов. Указатель на объект. Передача объектов как аргументов функции. Массивы объектов создаются так же, как массивы элементов, поэтому можно создавать многомерные массивы объектов. При создании массивов объекта в классе обязательно должен присутствовать конструктор, имеющий все параметры по умолчанию, конструктор без параметров, или, или вообще конструктора может не быть. Для доступа к членам объекта через сам объект используется оператор «точка» (.). Если же используется указатель на объект, тогда необходимо использовать оператор «стрелка» (—>). Использование операторов «точка» и «стрелка» аналогично их использованию для структур и объединений.
Объекты передаются таким же образом, как и переменные любого другого типа. При передаче по значению создаётся локальная копия объекта и любые изменения, происходящие с элементами объекта в функции, не изменяют его самого. Можно передать параметр объекта по ссылке, иными словами передать адрес объекта, в таком случае все изменения в функции изменят сам объект. При передаче объекта в качестве параметра по значению создаётся локальная копия объекта. Может быть вызван конструктор и деструктор, динамически выделена память.
П
ередача параметров по значению. Ключевое слово this. Аргументы могут передаваться по значению (by value) и по ссылке (by reference). При передаче аргументов по значению внешний объект, который передается в качестве аргумента в функцию, не может быть изменен в этой функции. В функцию передается само значение этого объекта. Например: Фунция выведет квадраты, но значениях самих чисел после останется тем же. Ключевое слово this представляет указатель на текущий объект данного класса. Соответственно через this мы можем обращаться внутри класса к любым его членам.
В случае если аргументы и поля класса имеют разные имена, указатель this при обращении к полям класса может быть опущен. Но в приведенном выше примере использование this указывает, что мы ходим обратиться именно к полю класса.
Перегрузка стандартных операций. Унарные и бинарные операции. Использование ключевого слова this. Перегрузку стандартных операций можно рассматривать как разновидность перегрузки функций, при которой в зависимости от типов данных, участвующих в выражениях, вызывается требуемый экземпляр операции. Примером такой перегрузки может являться операция сложения. C++ позволяет расширить область применимости этой операции, например, для сложения векторов в трёхмерном пространстве. Для этого нужно определить новое поведение стандартной операции “+” применительно к новым типам данных. Это допускается, если хотя бы один из операндов операции является объектом определённого пользователем класса. Не могут быть переопределены или перегружены: 1.операция условия «?» 2. уточнение области видимости «::» 3.sizeof Переопределение операции выполняется с помощью определения операторной функции следующего формата: Тип_результат operator#(список аргументов){операторы тела функции;} Каждая из функций операции имеет только один параметр, в то время как сами функции определяют бинарные операции. Другой аргумент неявно передаётся с this-указателем. Здесь this ассоциируется с объектом, предшествующим знаку операции. Если используются функции-члены, то не нужны параметры для унарных операций, и требуется лишь один параметр для бинарных операций.
П
ерегрузка постфиксных и префиксных операций ++, —. Дружественные функции операций. Использование ссылочных переменных. Особенность перегрузки этих операторов состоит в том, что нужно перегружать как префиксную так и постфиксную форму этих операторов. При указании перегруженного оператора для формы postfix оператора приращения или decrement дополнительный аргумент должен быть типа Int; указание любого другого типа генерирует ошибку. Отличие дружественных функций-операторов от обычных функций-операторов, членов класса, состоит в том что для них не используется указатель this При объявлении дружественной функции оператора должны передаваться два аргумента для бинарных операторов и один для унарных операций. Например.
Перегрузка унарных операцийДекремент дружественной функции требует использования ссылки. Friend vector operator ++ (vector &opl) { opl.x++; opl. y++; opl.z++; return opl; } Перегрузка операции индексации []Индексация —бинарная операция, где первый операнд —объект класса, второй —целочисленный индекс. Перегрузка операции индексации позволяет работать с элементами объекта vector, как с элементами массива. #include<iostream.h> class vector { int v[3]; public: vector(int a=0; int b=0; int c=0) { v[0]=a; v[1]=b; v[2]=c; } vector operator +(vector t); vector operator =(vector t); int & operator[](int i); void show(void); }; vector vector::operator+(vector t) { vector tmp; for (int i=0; i<3; i++) tmp.v[i]=t.v[i]+v[i]return tmp; } vector vector::operator=(vector t) { vector tmp; for (int i=0;i<3;i++) v[i]=t.v[i]; return *this; } int &vector::operator[](int i) { return v[i]; } void vector::show(void) { for (int i=0;i<3;i++) cout<<v[i]; } main(void) { vector v1(1,2,3), v2(10,11,12),v3;v3=v1+v2; for (int i=0;i<3;i++) cout<<v3[i]; v3.show(); v1[0]=100; v1[1]=201; v2[2]=302; v1.show(); }
Указатели на производные типы. Виртуальные функции. Виртуальные функции представляют собой функции-члены класса, которые переопределяются в производном классе. Механизм виртуальных функций обеспечивает динамический полиморфизм. Виртуальные функции –это функции, которые объявляются с использованием ключевого слова virtualв базовом классе и переопределяются в одном или нескольких производных классов. Прототипы функций должны быть одинаковы, иначе механизм переопределения не включается. Виртуальную функцию вызывают через указатель базового класса, используемого в качестве ссылки на объект производного класса. Если имеется несколько производных классов от содержащего виртуальную функцию базового класса, то при ссылке указателя базового класса на разные объекты производных классов будут выполнены различные версии виртуальных функций. В одном или нескольких производных классах перераспределение виртуальной функции может отсутствовать, при этом механизм виртуальной функции сохраняется, и вызывается функция базового класса, ближайшего к тому, где функция не переопределена, т.е. соблюдается иерархия наследственной характеристики. Виртуальная функция должна быть членом класса, она не может быть дружественной для класса, в котором определена, но может быть другом другого класса. Удобство виртуальной функции состоит в том, что базовый класс создаёт основной интерфейс, который будет иметь производный класс, производный класс задаёт свой метод.
Чистые виртуальные функции. Абстрактные типы. Виртуальные базовые классы.
Шаблоны. Шаблоны функций. Выбор экземпляра функций. Шаблоны –это одна из реализаций полиморфизма в С++. Шаблон представляет собой специальное описание родовой (параметризированной) функции или родового класса, в которой информация об используемых в реализации типов данных преднамеренно остаётся незаданной. Типы используемых данных передаются через параметры шаблона. Аппарат шаблона позволяет одну и ту же функцию или класс использовать с различными типами данных без необходимости программировать заново каждую версию функции или класса.Шаблон создаётся при помощи ключевого слова templateи угловых скобок <>со списком параметров, за которым следует описание класса или функции. Template<classфикт_имя1, classфикт_имя2 ...> Определение: Вместо ключевого слова class допускается использование ключевого слова typename. Шаблоны тождественны интеллектуальным макросам, которые способны сообщить компилятору о каждом случае использования шаблона новых типов данных. При выборе требуемого экземпляра функции осуществляется сравнение типов и числа параметров и аргументов:–параметры –формальные параметры функции,–аргументы –реальные значения при вызове функций. Существует три возможных варианта:1. точное соответствие типов аргументов параметрам одного из экземпляров функции.2. соответствие аргументов параметрам может быть достигнуто путём преобразования типов аргументов к типам параметров только для одного экземпляра функции. В этом случае компилятор пытается сначала выполнить стандартные преобразования, которые определены пользователем.3. соответствие может быть достигнуто более чем для одного экземпляра функции. При этом необходимо иметь ввиду, что преобразование типов, определённое пользователем, имеет меньший приоритет по сравнению со стандартным преобразованием. Если соответствие типов достигается путём равноправных преобразований, компилятор выдаёт сообщение об ошибке: «невозможно определить однозначно экземпляр функции».
Шаблоны классов. Выбор экземпляра класса. Стандартная библиотека шаблонов. Шаблоны позволяют определить конструкции (функции, классы), которые используют определенные типы, но на момент написания кода точно не известно, что это будут за типы. Иными словами, шаблоны позволяют определить универсальные конструкции, которые не зависят от определенного типа. Шаблоны классов позволяют построить отдельные классы аналогично шаблонам функций. Имя шаблона класса должно быть уникальным и не может относиться к какому-либо шаблону класса, функции или объекта.
Для применения шаблонов перед классом указывается ключевое слово template, после которого идут угловые скобки. В угловых скобках после слова typename идет параметр шаблона. Можно определить несколько параметров шаблона, в примере выше применяется только один параметр. Параметр шаблона представляет произвольный идентификатор, в качестве которого, как правило, применяюся заглавные буквы, например, T. Но это необязательно. То есть в данном случае параметр T будет представлять некоторый тип, который становится известным во время компиляции. Это может быть и тип int, и double, и string, и любой другой тип. И теперь идентификатор счета будет представлять тип, который передается через параметр T. В C++ переменная класса называется экземпляром или объектом класса. Точно так же, как определение переменной фундаментального типа данных (например, int x) приводит к выделению памяти для этой переменной, так же и создание объекта класса (например, DateClass today) приводит к выделению памяти для этого объекта.