§ 13. Объекты
Наследование, инкапсуляция и полиморфизм
01 C++ — это язык, который сочетает в себе сразу несколько подходов к программирования, и основным подходом считается объектно-ориентированный. Этот подход описывает предметную область вашей задачи, используя объекты и их методы. Объект — это абстрактное понятие, которое включает в себя объекты и процессы (физические, математические и другие), а метод — это абстрактный функционал, связанный с объектом.
02 Допустим, вы решили написать программу, которая моделирует качку судна. В этой программе у вас непременно будет объект судно
, параметрами которого будут углы поворота относительно каждой из осей координат, масса, геометрия и др., а одним из методов этого объекта будет повернуть судно на определенный угол вокруг заданной оси
, в котором угол и ось будут параметрами. Это называет инкапсуляцией: объект судно
скрывает в себе параметры, которые изменяются посредством вызова методов этого объекта и никак иначе.
03 Затем, вы решили написать программу, которая рисует на экране простые геометрические фигуры: треугольник, окружность, прямоугольник и т.п. В этой программе у вас непременно будут объекты, которые соответствуют каждой фигуре: объект треугольник
с координатами каждой точки в качестве параметров, объект окружность
с координатой центра и радиусом и объект прямоугольник
с координатой левого верхнего и правого нижнего угла. У каждого из этих объектов будет метод нарисовать
. Этот метод вызывается одинаково для каждого объекта, но реализация этого метода уникальна для каждого объекта. Это называется полиморфизмом — объекты разные, а функционал один и тот же и предоставляется через один и тот же интерфейс.
04 Наконец, вы решили написать программу, которая моделирует движение трехмерных объектов (компьютерную игру, например). Тогда в вашей программе обязательно появится объект, который является базовым для всех объектов, отображаемых на экране. Этот объект будет содержать координаты и какие-нибудь другие поля в качестве параметров. Все остальные объекты буду создаваться на его основе, наследуя все его параметры и методы. Это так и называется — наследование.
05 Инкапсуляция, наследование и полиморфизм являются основой объектно-ориентированного подхода к разработке программ. Такие программы состоят из объектов и методов, внутри которых вызываются методы других объектов, в которые еще одни объекты передаются в качестве параметров. Преимуществами данного подхода являются
- простота (все объекты взяты из предметной области задачи),
- возможность совместной разработки (изменения, которые необходимо внести в код для добавления новых возможностей, как правило, затрагивают небольшое количество объектов).
Классы
06 В С++ для создания объекта сначала надо определить его класс. Это делается с помощью ключевого слова class
. Класс является описанием общедоступного интерфейса объекта и содержит в себе список полей, список методов и список типов. Для каждого элемента класса определяется уровень доступа: private
— элемент доступен только внутри класса, protected
— элемент доступен внутри класса и во всех классах-наследниках, public
— элемент доступен из любого контекста. Как правило, все поля класса делают доступными только внутри класса, а для доступа к ним используют общедоступные методы. Это выгодно, если надо измененить реализацию класса: поля можно поменять без изменения методов. Скрытые методы и типы используют для сокрытия внутренней реализации класса. Уровни доступа работают только на этапе компиляции, во время запуска программы они ни на что не влияют.
07 Для создания объекта используется тот же синтаксис, что и для объявления и определения переменных, но с указанием класса в качестве типа переменной. Для объектов объявление и определения совмещено, и при объявлении сразу вызывается конструктор соответствующего класса, а когда программа выходит из блока кода, в котором был объявлен объект, то вызывается деструктор класса. Конструктор и деструктор являются методами класса, вызов которых происходит автоматически. Привязка вызова этих методов к синтаксической структуре программы является главным отличием C++ от других языков.
08 Конструкторы используются для инициализации полей объекта. Это можно сделать, передав в конструктор аргументы, и, написав в теле конструктора код, вычисляющий значения полей. Для полей, которые не были проинициализированы, вызывается конструктор по умолчанию (конструктор без аргументов), а для примитивных типов конструктор не вызывается, и такие поля имеют произвольные значения.
09 Деструкторы используются для освобождения ресурсов, которые были выделены в конструкторе. Обычно, это оперативная память, но может быть и любой другой системный ресурс, например, файловый дескриптор. Для всех полей деструкторы вызываются автоматически.
10 Методы класса можно объявить — то есть указать имя, типы аргументов и тип возвращаемого значения, — а можно определить — то есть написать тело метода. Для простых методов объявление и определение обычно совмещают, то есть сразу после объявления пишут тело метода. Это выгодно с точки зрения производительности, поскольку тела таких методов вставляются в место вызова оптимизатором (при условии, что они достаточно небольшие), и экономятся инструкции необходимые для вызова метода. Для сложных методов объявление и определения пишутся отдельно: объявление пишут в заголовочном файле, а определение — в основном файле. Сами файлы называют по имени класса. Если вы хотите, чтобы совместное объявление и определение работало корректно, то необходимо добавить ключевое слово inline
к нему. Если метод не изменяет поля объекта, то добавляют ключевое слово const
к его определению.
Задания
Point1 балл
11 Создайте класс Point
, который представляет собой точку в трехмерном пространстве. Напишите программу, в которой создаются объекты этого класса и выводятся на экран их координаты. Нужна ли инкапсуляция для этого класса?
Rectangle1 балл
12 Создайте класс Rectangle
, который представляет собой прямоугольник в двухмерном пространстве. Напишите программу, в которой создаются объекты этого класса и выводятся на экран их параметры. Нужна ли инкапсуляция для этого класса? Какие наборы полей можно использовать для описания прямоугольника?
Triangle1 балл
13 Создайте класс Triangle
, который представляет собой треугольник в трехмерном пространстве. В классе должно быть не больше трех полей. Напишите программу, в которой создаются объекты этого класса и выводятся на экран их параметры.
Ship2 балла
14 Создайте класс Ship
, который представляет собой судно в трехмерном пространстве. Параметрами судна являются масса и углы поворота по каждой из осей. Методом класса является метод rotate
, который поворачивает судно на указанный угол вокруг указанной оси. Напишите объявление класса в файле ship.hh, определение методов — в файле ship.cc, а функцию main
— в файле main.cc. Как можно изменить поля, так чтобы упростить реализацию метода rotate
?