Главная страница

Общие понятия


Скачать 134.7 Kb.
НазваниеОбщие понятия
Дата16.06.2018
Размер134.7 Kb.
Формат файлаdocx
Имя файлаVoprosy_k_ekzame.docx
ТипДокументы
#47047
страница3 из 3
1   2   3

ООП в С++


    1. Объектно-ориентированная парадигма программирования, ее характеристики.

Паради́гма программи́рования — это совокупность идей и понятий, определяющих стиль написания компьютерных программ

Объектно-ориентированная парадигма (ООП) представляет программу как набор объектов и их взаимодействий. Основными понятиями ООП являются следующие:

  • объект — элементарная сущность, описываемая определенными свойствами (хранящимися в виде атрибутов объекта) и поведением (реализованным в виде методов);

  • класс описывает структуру свойств и поведения одного типа объектов. Каждый объект программы является экземпляром некоторого класса;

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

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

    1. Класс, члены класса. Определение класса. Реализация класса.

Класс – это способ описания сущности, определяющий состояние и поведение, зависящее от этого состояния, а также правила для взаимодействия с данной сущностью.

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

Члены класса: поля, константы, св-ва, методы, события, операторы, итераторы, конструкторы, методы завершения, вложенные типы.

    1. Виды функций – членов: метод, друг, внешняя функция.

Функция «Метод» - это вложенная функция в классе, которая взаимодействует с данными полями.
Дружественная функция — это функция, которая не является членом класса, но имеет доступ к членам класса, объявленным в полях private или protected.

Внешняя функция – это функция, которая вынесена из определенного класса.

    1. Конструктор, деструктор. Виды конструкторов. Виды деструкторов.

Конструктор — это особая функция-член, инициализирующая экземпляр своего класса.

Деструкторы представляют собой противоположность конструкторам. Они вызываются при уничтожении (отмене выделения памяти) объектов.

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

Виды деструкторов: простой, виртуальный.

    1. Копирующий конструктор. Назначение. Применение.

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

Такую «реальную» копию объекта надо создавать в нескольких случаях:

  • когда мы передаем объект в какую-либо функцию в виде параметра;

  • когда какая-либо функция должна вернуть объект класса в результате своей работы;

  • когда мы в главной функции один объект класса инициализируем другим объектом класса.

    1. Объект. Вызов метода.

Объе́кт в программировании — некоторая сущность в компьютерном пространстве, обладающая определённым состоянием и поведением, имеющая заданные значения свойств (атрибутов) и операций над ними (методов)

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

Вызов метода происходит через обращение к объекту определенного класса, а потом уже идет указание самого метода. То есть: MyClass object; object.method();

    1. Инкапсуляция, ограничение доступа к членам класса. Основные принципы инкапсуляции.

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

    1. Дружественные функции: назначение, определение.

Дружественная функция — это функция, которая не является членом класса, но имеет доступ к членам класса, объявленным в полях private или protected.

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

    1. Перегрузка функций. Шаблонные функции.

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

Шаблонные функции могут работать принимать переменные разных типов данных, но иметь одинаковую логику. Для обозначения типа данных шаблонным, надо написать template <typename T>

    1. Механизм перегрузки операций. Перегрузка бинарных, унарных операций, присваивания, индексации, потоков ввода-вывода.

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

Тип operator @ (список_параметров-операндов)

{

// … тело функции …

}

где @ — знак перегружаемой операции



А также бинарные. К примеру, =,==, *,/,+,- и т.п.

Перегрузка на примере перегрузки индексации:

int& operator [](const int idx) { return vec[idx]; }

Перегрузка на примере перегрузки потока вывода:

friend ostream& operator<<(ostream& os, const Date& dt);


    1. Методы создания новых классов

      1. Наследование. Простое, множественное. Конструкторы в производных классах. Деструкторы в производных классах. Алгоритм создания объекта производного класса. Алгоритм уничтожения производного класса.

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



Множественное наследование: Построение производного класса на основе нескольких базовых выглядит очень просто: вместо имени одного базового класса (вместе с его атрибутом) используется список имен, разделенный запятыми

Конструктор производного класса всегда вызывает конструктор базового класса, чтобы перед выполнением любых дополнительных операций иметь в своем распоряжении полностью созданные базовые классы. Конструкторы базовых классов вызываются в порядке наследования — например, если ClassA является производным от ClassB, который является производным от ClassC, сначала вызывается конструктор ClassC, затем конструктор ClassB и последним конструктор ClassA.

Если базовый класс не имеет конструктор по умолчанию, в конструкторе производного класса необходимо указать параметры конструктора базового класса.
Если базовый класс или элемент данных имеет доступный деструктор, а производный класс не объявляет такой деструктор, он создается компилятором. Этот созданный компилятором деструктор вызывает деструктор базового класса и деструкторы для членов производного типа. Деструкторы по умолчанию являются открытыми.
Объекты производного класса свободно могут использовать всё, что создано и отлажено в базовом классе.
у производных классов деструкторы от базовых классов вызываются только при условии что деструктор объявлен виртуальным. Иначе возникает утечка памяти

      1. Композиция.

Композиция – класс строго связан с другим классом. (Вложенный класс в классе)

      1. Агрегация.

Агрегация – класс не строго связан с другим классом.

    1. Полиморфизм. Ранний, поздний. Правила полиморфизма. Реализация механизма позднего полиморфизма.

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

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

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

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


    1. Событийное программирование (определение, особенность реализации, примеры).

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

Особенность реализации: удобнее для описания каких-либо событий, которые происходят при определенных сигналах. То есть, (пример): когда пользователь нажимает кнопку, совершается событие, при котором происходят определенные операции.

    1. Применение класса string. Представление в памяти. Конструкторы. Операции (перегруженные). Методы: empty , size , length , max_size , reserve , clear , insert , erase , push_back , pop_back , append , operator+= , compare , replace , substr , copy , resize , swap ,   , Поиск в строке , find , rfind , find_first_of , find_first_not_of , find_last_of , find_last_not_of .

Применение: подключив библиотеку , можем создать строку класса string:
string mystr = “Hello World”;

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

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

Методы:

Empty-пустая ли строчка, size = length – длина строки, max_size – возвращает максимальный размер строчки, reserve – запрашивает изменение ёмкости, clear – очищает строчку, insert – вставляет в строчку символы, erase, очищает какие-то символы, push_back – добавляет символ в конец, pop_back – удаляет последний символ, append – добавляет символы в строку, operator+= - Оператор реализующий присваивание переменной типа string, compare – сравнивает строчки, replace – заменяет содержимое строчки, substr - Bозвращает n символов строки str начиная с позиции pos, copy – копирует последовательность символов из строки, resize – изменяет размер строчки, swap – меняет строковые значения, find- находит элемент в строчке, rfind – находит последнее вхождение содержимого в строку, find_first_of – находит символ в строке, find_first_not_of – находит отсутствие символа в строке, find_last_of – находит символ в строке с конца, find_last_not_of - Найти несогласованный символ в строке с конца.

    1. Шаблонный класс. Определение. Правила реализации. Применение таких классов. Реализация шаблона – динамический массив.

Тот же класс, только имеет шаблон для типа данных, как у функций.

Правило реализации: чтобы класс был шаблонным, нужно перед его созданием написать так:

Template

Class Myclass{public: T a; T b};

Такие классы обычно применяются для того, чтобы при создании объекта мы могли созданным переменным назначить определенный тип данных

Реализация шаблона:

Template

Class Arr{private: T *array};

То есть, создается шаблон. Далее создается указатель на массив типа данных Т. Далее все методы и операции над массивами будут соответствовать обычным, но будут зависимы от типа данных Т.

    1. STL. Ее назначение. Основные категории элементов и их назначение. Контейнеры: vector, set. Двумерный массив на основе вектора. Применение итератора.

Stl – стандартная библиотека шаблонов. Каждая STL коллекция имеет собственный набор шаблонных параметров, который необходим ей для того, чтобы на базе шаблона реализовать тот или иной класс, максимально приспособленный для решения конкретных задач.

В библиотеке выделяют пять основных компонентов:

  1. Контейнер (англ. container) — хранение набора объектов в памяти.

  2. Итератор (англ. iterator) — обеспечение средств доступа к содержимому контейнера.

  3. Алгоритм (англ. algorithm) — определение вычислительной процедуры.

  4. Адаптер (англ. adaptor) — адаптация компонентов для обеспечения различного интерфейса.

  5. Функциональный объект (англ. functor) — сокрытие функции в объекте для использования другими компонентами.

Контейнер vector подобен массиву, но работа с ним гораздо проще. (Самый банальный пример – добавление элемента в динамический массив. Для этого придется создать новый динамический массив, перенести все элементы из старого в новый, добавить также новый элемент в нужную позицию, удалить выделенную память старого, а потом поменять указатель на новую область в памяти. БЛАГОДАРЯ vector.insert() мы можем это сделать, просто указав в параметрах вызываемого метода позицию и значение)

В STL есть замечательный контейнер — set, он реализует такие сущности как множество и мультимножество. По сути это контейнеры, которые содержат некоторое количество отсортированных элементов. При добавлении нового элемента в множество он сразу становится на свое место так, чтобы не нарушать порядка сортировки. Потому как в множестве и мультимножестве все элементы сортируются автоматически.
std::vector<std::vector<int>> matr;//двумерный массив на основе вектора
Применение итератора:
Vector<int> v = {5,7,9};

Vector::iterator it; ------ //создаем итератор it
For (it =v.begin();it!=v.end();it++) ------ //применяем итератор it для вывода элементов массива

Cout<<*it<<” “;
Краткое описание итератора:

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


    1. Файловые потоки. Иерархия потоков С++. Буферизация файлового ввода и вывода. Текстовый файл как структура данных. Последовательный способ организации файла. Методы доступа к элементам (записям) файла. Двоичный файл как структура данных. Классы ifstream, ofstream, fstream, их назначение. Операции: открыть файл, закрыть файл – их назначение и физическое исполнение. Режимы открытия файла. Организация произвольного доступа к записям файла. Применение методов seekg, seekp. Операция добавления нового элемента в файл – алгоритм реализации. Алгоритмы вставки нового элемента в произвольную позицию: в текстовый файл, в двоичный файл. Удаление потока.

Файлом называют последовательность байтов, хранящихся на внешнем носителе информации. Под доступом к файлу понимают запись и чтение данных из файла. Потоком называется логический интерфейс (программа), который обеспечивает доступ к файлу. Прежде чем использовать поток для доступа к файлу, его необходимо соединить с этим файлом, то есть обеспечить поток информацией о файле. Эта информация хранится в структуре типа FILE. Потому считается, что поток имеет тип FILE*, то есть является указателем на файл. Когда поток соединяют с файлом, то говорят, что файл открывают. Когда поток отсоединяют от файла, то говорят, что файл закрывают.

С++ обеспечивает поддержку системы ввода/вывода в заголовочном файле iostream.h. В этом файле определены две иерархии классов, поддерживающие операции ввода/вывода. Классом нижнего уровня является streambuf. Этот класс обеспечивает базовые операции ввода/вывода. До тех пор, пока не вводятся свои собственные классы ввода/вывода, непосредственно streambuf не используется. Вторая иерархия классов начинается с класса ios. Он обеспечивает поддержку форматированного ввода/вывода. От него порождены классы istream, ostream и iostream. Эти классы использованы для создания потоков, способных осуществлять ввод, вывод и ввод/вывод соответственно.

Принцип "потокового ввода-вывода" следующий:

  1. В оперативной памяти средствами операционной системы создаётся некоторый "промежуточный буфер" для хранения данных, читаемых из файла, устройства или записывания на него этих данных;

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

  3. Средствами операционной системы осуществляется "синхронизация" этого буфера ("потока данных") с файлом или устройством;

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

В буфер заносятся только символьные данные.

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

В текстовом режиме поток записывает и читает из файла текстовые строки, которые заканчиваются символом ‘\n’. По стандарту поток должен обеспечивать обработку строк длиной не менее 254 символа, включая символ ‘\n’. Стандартом допускается, что при чтении и записи данных текстовым потоком может происходить их преобразование.

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

Функция-элемент Write класса Ostream выводит фиксированное число байтов, начиная с от заданного места в памяти, в заданный поток. Функция-элемент Read класса

Istream вводит фиксированное число байтов из заданного потока в область памяти.

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

Неформатированный ввод-вывод осуществляется с помощью функций-членов Get(), Put(), Read() И Write() соответствующих классов istream, ostream, iostream. При этом можно выделить два варианта организации: строко-ориентированный и символьный. Первый вариант удобен для работы с текстовыми файлами. Символьный ввод-вывод используется в первую очередь для работы с бинарными файлами.

В С++ файлу не предписывается никакая структура. Для последовательного поиска данных в файле программа обычно начинает считывать данные с начала файла до тех пор, пока не будут считаны требуемые данные. При поиске новых данных этот процесс вновь повторяется.

В системе ввода–вывода C++ предусмотрена возможность управления двумя указателями, связанными с файлом. Эти, так называемые get- и put-указатели, определяют, в каком месте файла должна выполниться следующая операция ввода или вывода соответственно. При каждом выполнении операции ввода или вывода соответствующий указатель автоматически перемещается в указанную позицию. Как класс istream, так и класс ostream, содержат функции для управления этими указателями – функцию seekg() и функцию seekp(), прототипы которых имеют следующий вид:

istream& seekg(offset, origin);

ostream& seekp(offset, origin);

Функция seekg() перемещает текущий get-указатель соответствующего файла на offset-байт относительно позиции, заданной параметром origin.

Функция seekр() перемещает текущий put-указатель соответствующего файла на offset-байт относительно позиции, заданной параметром origin. Параметр origin определён как константа в классе ios и может принимать следующие значения:

ios:: beg поиск с начала файла

ios::cur поиск от текущей позиции в файле

ios::end поиск с конца файла

Используя функции seekg() и seekp(), можно получить доступ к информации в файле в произвольном порядке.

Потоки для работы с файлами создаются как объекты следующих классов:
ofstream - для вывода (записи) данных в файл;

ifstream - для ввода (чтения) данных из файла;

fstream - для чтения и для записи данных (двунаправленный обмен).

Чтобы использовать эти классы, в текст программы необходимо включить дополнительный заголовочный файл fstream.h. После этого в программе можно определять конкретные файловые потоки, соответствующих типов (объекты классов ofstream, ifstream, fstream), например, таким образом:

ofstream outFile; // Выходной файловый поток.

ifstream inFile; // Входной файловый поток.

fstream ioFile; // Файловый поток для ввода и вывода.

Создание файлового потока (объекта соответствующего класса) связывает имя потока с выделяемым для него буфером и инициализирует переменные состояния потока. Так как перечисленные классы файловых потоков наследуют свойства класса ios, то и переменные состояния каждого файлового потока наследуются из этого базового класса. Так как файловые классы являются производными от классов ostream (класс ofstream), istream (класс ifstream), stream (класс fstream), то они поддерживают описанный в предыдущих шагах форматированный и бесформатный обмен с файлами. Однако прежде чем выполнить обмен, необходимо открыть соответствующий файл и связать его с файловым потоком.
Открытие файла в самом общем смысле означает процедуру, информирующую систему о тех действиях, которые предполагается выполнять с файлом. Существуют функции стандартной библиотеки языка С для открытия файлов fopen(), open(). Но работая с файловыми потоками библиотеки ввода-вывода языка С++, удобнее пользоваться компонентными функциями соответствующих классов.
Создав файловый поток, можно "присоединить" его к конкретному файлу с помощью компонентной функции open(). Функция open() унаследована каждым из файловых классов ofstream, ifsream, fstream от класса fstreambase.

1Открытие файла


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

  • open(путь)

  • open(путь, режим)

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

  • ios::in: файл открывается для ввода (чтения). Может быть установлен только для объекта ifstream или fstream

  • ios::out: файл открывается для вывода (записи). При этом старые данные удаляются. Может быть установлен только для объекта ofstream или fstream

  • ios::app: файл открывается для дозаписи. Старые данные не удаляются.

  • ios::ate: после открытия файла перемещает указатель в конец файла

  • ios::trunc: файл усекается при открытии. Может быть установлен, если также установлен режим out

  • ios::binary: файл открывается в бинарном режиме

Если при открытии режим не указан, то по умолчанию для объектов ofstream применяется режим ios::out, а для объектов ifstream - режим ios::in. Для объектов fstream совмещаются режимы ios::out и ios::in.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

std::ofstream out;          // поток для записи

out.open("D:\\hello1.txt"); // окрываем файл для записи

     

std::ofstream out2;

out2.open("D:\\hello2.txt", std::ios::app); // окрываем файл для дозаписи

 

std::ofstream out3;

out2.open("D:\\hello3.txt", std::ios::out | std::ios::trunc); // установка нескольких режимов

 

std::ifstream in;       // поток для чтения

in.open("D:\\hello4.txt"); // окрываем файл для чтения

 

std::fstream fs;        // поток для чтения-записи

fs.open("D:\\hello5.txt"); // окрываем файл для чтения-записи


std::fstream fs("D:\\hello.txt", std::ios::app);
После завершения работы с файлом его следует закрыть с помощью функции close(). Также стоит отметить, то при выходе объекта потока из области видимости, он удаляется, и у него автоматически вызывается функция close.
Чтобы вставить строку в середину файла, используя вспомогательный файл, необходимо проделать следующий алгоритм.
Открыть входной файл в режиме чтения и вспомогательный файл в режиме записи (этот файл будет создан автоматически).

Прочесть из входного файла текст до места вставки.

Записать прочитанный фрагмент во вспомогательный файл.

Записать во вспомогательный файл вставляемый фрагмент.

Прочесть из входного файла остаточный фрагмент и записать его во вспомогательный файл.

Закрыть оба файла.
Функция write пишет последовательность символов (байтов) в файл. Эта функция имеет следующий прототип:
ostream& write ( const char* s , size n );
где s указывает на область памяти, из которой данные записываются в файл, а n – количество записываемых символов (байтов). Отметим, что эта функция используется для записи данных в бинарные файлы, то есть содержимое области памяти записывается в файл без изменения.
1   2   3


написать администратору сайта