
- •Принципы ооп:
- •Ооп, как средство обеспечения требований предъявляемых к современному программному обеспечению
- •Причины использования перегрузки функций
- •Конструкторы и деструкторы производных классов.
- •Полиморфизм и виртуальные функции, раннее и позднее связывание.
- •Форматирование данных, флаги и манипуляторы потоков.
- •Пример форматирования
- •Манипуляторы без параметров:
- •Int I, // параметр обычного типа
Парадигма объектно-ориентированного подхода в программировании, инкапсуляция, наследование и полиморфизм. ООП, как средство обеспечения требований предъявляемых к современному программному обеспечению.
Парадигма – набор теорий, стандартов и методов, которые совместно представляют собой способ организации научного знания, – иными словами, способ видения мира.
Парадигма в программировании – способ концептуализации, который определяет, как следует проводить вычисления, и как работа, выполняемая компьютером, должна быть структурирована и организована.
Объектно-ориентированное программирование (ООП)* – парадигма программирования, в которой основными концепциями являются понятия объектов и классов (либо, в менее известном варианте языков с прототипированием, – прототипов).
Класс – это тип, описывающий устройство объектов. Говорят, что объект – это экземпляр класса. Класс является описываемой на языке терминологии (пространства имён) исходного кода моделью ещё не существующей сущности, т.н. объекта.
Объект – сущность в адресном пространстве вычислительной системы, появляющаяся при создании экземпляра класса (например, после запуска результатов компиляции и линковки исходного кода на выполнение).
Прототип – это объект-образец, по образу и подобию которого создаются другие объекты.
Принципы ооп:
– Абстракция данных – объекты представляют собою упрощенное, идеализированное описание реальных сущностей предметной области. Если соответствующие модели адекватны решаемой задаче, то работать с ними оказывается намного удобнее, чем с низкоуровневым описанием всех возможных свойств и реакций объекта.
– Инкапсуляция – это принцип, согласно которому любой класс должен рассматриваться как чёрный ящик – пользователь класса должен видеть и использовать только интерфейсную часть класса (т. е. список декларируемых свойств и методов класса) и не вникать в его внутреннюю реализацию. Поэтому данные принято инкапсулировать в классе таким образом, чтобы доступ к ним по чтению или записи осуществлялся не напрямую, а с помощью методов.
– Сокрытие данных – неотделимая часть ООП, управляющая областями видимости. Является логическим продолжением инкапсуляции. Целью сокрытия является невозможность для пользователя узнать или испортить внутреннее состояние объекта
– Наследование – это возможность порождать один класс от другого с сохранением всех свойств и методов класса-предка (прародителя, суперкласса) и добавляя, при необходимости, новые свойства и методы. Набор классов, связанных отношением наследования, называют иерархией. Наследование призвано отобразить такое свойство реального мира, как иерархичность.
– Полиморфизм – это явление, при котором функции (методу) с одним и тем же именем соответствует разный программный код (полиморфный код) в зависимости от того, объект какого класса используется при вызове данного метода. Полиморфизм обеспечивается тем, что в классе-потомке изменяют реализацию метода класса-предка с обязательным сохранением сигнатуры метода. Это обеспечивает сохранение неизменным интерфейса класса-предка и позволяет осуществить связывание имени метода в коде с разными классами – из объекта какого класса осуществляется вызов, из того класса и берётся метод с данным именем. Такой механизм называется динамическим (или поздним) связыванием – в отличие от статического (раннего) связывания, осуществляемого на этапе компиляции.
Ооп, как средство обеспечения требований предъявляемых к современному программному обеспечению
– Повторное использование
«Объект» это логический объект, у которого есть комплект свойств и методов, и он может взаимодействовать с другими объектами. Объект может быть абсолютно независимым или может зависеть от других объектов. Объект обычно создают для решения специфических поставленных проблем. Следовательно, когда другие разработчики сталкиваются с похожими проблемами, они могут подключить ваш класс к своему проекту и использовать его, не боясь, что он нарушит процесс их разработки. Это позволяет избежать DRY, что расшифровывается как Don’t Repeat Yourself (не повторяйся).
– Рефакторинг*
Когда вам необходимо в проекте использовать рефакторинг, ООП предоставляем вам максимум преимуществ, так как все объекты это маленькие элементы и содержат свои свойства и методы как часть себя. Поэтому использовать рефакторинг относительно легко.
– Расширяемость
Если вам необходимо расширять функциональность вашего проекта, вы можете достичь лучших результатов при помощи ООП. Одна из основных функциональностей ООП это расширяемость. Вы можете использовать рефакторинг объектов, чтобы добавить функциональность. Работая над этим, вы можете сохранить прежнюю совместимость объекта – следовательно, вы можете прекрасно работать и с прежним кодом. Или же вы можете расширить объект и создать абсолютно новый, который будет содержать все необходимые свойства и методы родительского объекта, от которого происходит новый, а потом уже добавить в него новые функции. Это называется “наследование” и это очень важная возможность ООП.
– Поддержка
Объектно-ориентированный код легче поддерживать, так как он следует весьма жёстким соглашениям написания кода и пишется в самопоясняющейся форме. К примеру, когда разработчик дополняет, перерабатывает код, или отлаживает его, он может легко найти внутреннюю структуру кода и поддерживать код время от времени.
Более того, когда в вашем окружении работает команда разработчиков, ООП может быть лучшим решением, так как вы можете распределять ваш код между членами команды, после разбития его на маленькие части. Эти маленькие части могут быть разработаны как отдельные объекты, следовательно, разработчики могут работать практически независимо друг от друга. В конечном итоге, объединить все части в одно приложение не составит большого труда.
– Эффективность
Идея ООП в действительности была разработана для повышения эффективности и облегчения процесса разработки. Несколько шаблонов проектирования разработаны, что бы создавать более эффективный и хороший код.
Более того в ООП вы можете вы можете размышлять над вашими решениями в более удобной форме чем в процедурном подходе. Поскольку вы разбиваете вашу проблему на несколько маленьких проблем и вы находите решение для каждой из них отдельно, большая проблема решается сама по себе.
*Рефакторинг – процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы. В основе рефакторинга лежит последовательность небольших эквивалентных (то есть сохраняющих поведение) преобразований. Поскольку каждое преобразование маленькое, программисту легче проследить за его правильностью, и в то же время вся последовательность может привести к существенной перестройке программы и улучшению её согласованности и четкости. Рефакторинг позволяет разрабатывать архитектуру программы постепенно, откладывая проектные решения до тех пор, пока не станет более ясной их необходимость.
Классы и объекты. Члены класса: - данные, методы и указатель this. Статус доступа к данным и методам класса. Конструктор и деструктор, их назначение, синтаксис и вызов. Конструктор по умолчанию, конструктор без параметров, конструктор копии, конструктор-инициализатор.
Класс. В широком смысле – это пользовательский тип, объявленный с использованием одного из ключевых слов class, struct или union. В узком смысле класс – это пользовательский тип, объявленный с использованием ключевого слова class.
Определение класса состоит из двух частей: заголовка, включающего ключевое слово class, за которым следует имя класса, и тела, заключенного в фигурные скобки. После такого определения должны стоять точка с запятой или список объявлений:
class Example {
int X;
void PrintData();
} P1, P2, *P3;
Объект – это переменная определенного пользователем типа, экземпляр класса, совокупность данных (полей) и функций (методов) для их обработки. Пример:
class Example {...}; Example P; // P – объект класса Example.
Если класс можно рассматривать как тип данных, то объект – как переменную (по аналогии).
Поле класса (данные) – переменная, связанная с классом или объектом. Все данные объекта хранятся в его полях. Доступ к полям осуществляется по их имени. Обычно тип данных каждого поля задаётся в описании класса, членом которого является поле. Пример:
class Example {int X;...}; // X – поле класса Example.
Example P1, *P2; ... P1.X; P2->X; // обращение к данным класса.
Метод (функция-член) – встроенная функция, для обработки данных класса. Метод объявлен в области видимости своего класса, следовательно, его имя не видно за пределами этой области. К методу можно обратиться с помощью одного из операторов доступа к членам класса – точки (.) или стрелки (->):
Функции-члены имеют право доступа как к открытым, так и к закрытым членам класса, тогда как обычным функциям доступны лишь открытые. Пример:
class Example {...void PrintData();} // PrintData – метод класса.
Example P1, *P2; ... P1.PrintData(); P2->PrintData(); // вызов метода.
Указатель this. Когда функция-член вызывается для обработки какого-либо объекта, этой функции автоматически и неявно передается указатель на тот объект. Этот указатель имеет фиксированное имя this и незаметно для программиста определен в каждой функции класса следующим образом:
имя_класса * const this=адресс_обрабатываемого объекта.
Указатель this удобно использовать в тех случаях, когда в теле, принадлежащей классу функции нужно явно задавать тот объекта, для которого она вызвана. Например, если в классе нужна функция, помещающая адрес выбранного объекта класса в массив.
Статус доступа.
Компоненты класса получают атрибуты доступа либо по умолчанию (в зависимости от ключа класса и местоположения объявления), либо при использовании какого-либо из спецификаторов доступа: public, private или protected. Значение этих атрибутов следующие:
– public – компонент может быть использован любой функцией.
– private – компонент может быть использован только функциями-компонентами и "друзьями" класса, в котором он объявлен.
– protected – то же самое, что для private, но кроме того, компонент может быть использован функциями компонентов и друзьями классов, производных от объявленного класса.
Спецификаторы доступа не влияют на объявления функций типа friend.
Конструктор – специальный блок инструкций, вызываемый при создании объекта, как при его появлении, так и при использовании ключевого слова new.
Конструктор схож с методом, но отличается тем, что не имеет явным образом определённого типа возвращаемых данных, не наследуется, и обычно имеет различные правила для рассматриваемых модификаторов. Задача конструктора – инициализировать члены объекта.
В большинстве языков конструктор может быть перегружен, что позволяет использовать несколько конструкторов в одном классе, причём каждый конструктор может иметь различные параметры. Некоторые языки различают несколько особых типов конструкторов:
– конструктор по умолчанию – конструктор без параметров, не имеет обязательных аргументов;
– конструктор копирования – конструктор, принимающий в качестве аргумента объект того же класса (или ссылку из него);
– конструктор преобразования.
– Конструктор по умолчанию – конструктор, не принимающий аргументов. Используется при создании массивов объектов, вызываясь для создания каждого экземпляра. В отсутствие явно заданного конструктора по умолчанию его код генерируется компилятором (что на исходном тексте, естественно, не отражается). Пример:
class MyClass {...MyClass();...}; // конструктор по умолчанию
– Конструктор копирования – конструктор, аргументом которого является ссылка на объект того же класса. Применяется в C++ для передачи объектов в функции по значению.
Конструктор вызывается, когда новый объект создается путем копирования существующего:
– при передаче нового объекта с инициализацией другим объектом;
– при передаче объекта в функцию по значению;
– при возврате объекта из функции.
class MyClass {...MyClass(const MyClass C&);...}
– Конструктор преобразования – конструктор, принимающий один аргумент. Задаёт преобразование типа своего аргумента в тип конструктора. Такое преобразование типа неявно применяется, только если оно уникально.
Конструктор-инициализатор. Объекты классов с конструкторами могут быть инициализированы при помощи задаваемых в круглых скобках списков инициализаторов. Этот список используется как список передаваемых конструктору аргументов. Либо он может использовать находящийся до тела функции список инициализаторов:
class X{
int a, b;
public:
X (int i, int j) : a(i), b(j) {...};
};
В обоих случаях инициализация X вида x(1,2) присваивает значение 1 x::a и значение 2 x::b. Второй способ, а именно список инициализаторов, обеспечивает механизм передачи значений конструкторам базового класса.
Деструктор – специальный метод класса, служащий для деинициализации объекта (например освобождения памяти). Обозначается, как конструктор, но с тильдой перед идентификатором имени.
class MyClass {...~MyClass();...}; // деструктор класса.
Перегрузка функций. Перегрузка операций (унарных, бинарных), как внутри, так и вне класса. Причины необходимости перегрузки конструктора копии и операции присваивания.
Перегрузка функций – механизм, дающий возможность определения и использования функций с одинаковым именем, но различными наборами параметров, по которым C++ и различает эти функции. Это облегчает написание программы, когда требуется написать несколько функций, выполняющих сходные действия над различными наборами данных.
int add_values (int a, int b) {return(a + b);}
int add_values (int a, int b, int c) {return(a + b + c);}
void main(void) {
int s1 = add_values (3,4);
int s2 = add_values (5,6,7);}