- •Лабораторная работа № 3 создание классов и объектов
- •Теоретическая часть
- •2. Порядок выполнения лабораторной работы
- •3. Контрольные вопросы
- •Лабораторная работа № 4 конструкторы и деструкторы
- •Теоретическая часть
- •2. Порядок выполнения лабораторной работы
- •3. Содержание отчета
- •4. Контрольные вопросы
- •Лабораторная работа №5 простое и множественное наследование
- •1. Теоретическая часть Одно из преимуществ системного программирования – многократное использование разработанных объектов. Реализовать это преимущество позволяет механизм наследования.
- •Рассмотрим пример. Создадим класс, описывающий фигуру с координатами X, y и z. Класс содержит члены – функции, которые устанавливают и возвращают каждую координату отдельно.
- •2. Порядок выполнения лабораторной работы
- •3. Содержание отчета
- •4. Контрольные работы
- •Содержание
Лабораторная работа № 3 создание классов и объектов
Цель работы: ознакомление с форматом описания классов на языке С++, с созданием объектов класса, приобретение навыков программирования и использования классов.
Теоретическая часть
В основе системного программирования лежит представление программной системы как совокупности взаимодействующих друг с другом объектов, каждый из которых является экземпляром определенного класса.
В С++ объект – абстрактное описание какой - либо сущности. Объект включает в себя все данные, которые необходимы, чтобы описать сущность, и функции, которые манипулируют этими данными. В С++ объекты вводятся через понятие класса.
Класс – определенный пользователем тип данных, который используется для описания абстрактного объекта, предоставляя таким образом возможность использовать системное программирование.
В описание класса входят отдельные элементы. Эти элементы могут быть данными, которые называются данными–членами класса, или функциями, которые называются функциями - членами класса.
Данные–члены класса могут иметь любой тип, как определенный в С++, например int или double, так и определенный пользователем, в том числе другие классы. Функции-члены манипулируют данными-членами, создают и уничтожают объекты класса.
Данные - члены и функции – члены имеют атрибут: видимость. Так же, как обычные глобальные переменные видны во всех функциях, а локальные переменные – нет, каждая переменная – член класса может быть описана как видимая везде или не везде. Видимость членов класса определяется метками видимости. В С++ есть три уровня видимости: частный (private), общий (public) и защищенный (protected).
Если данные - члены класса объявлены как private – частные, то к этим членам имеют доступ только функции – члены этого класса, а любые другие функции к частным членам доступа не имеют. Таким образом, обеспечивается принцип скрытия данных – один из основных принципов системного программирования.
Объявление члена класса с меткой public - общий делает этот член доступным и для функций – членов класса, и для любых других функций. Общие члены класса называются общим интерфейсом класса.
Хорошо разработанный интерфейс обычно включает в себе функции – члены, которые выполняют следующие действия:
Создают и инициализируют объекты;
Освобождают память, используемую под объект;
Производят первоначальную установку значений частных переменных членов класса;
Вычисляют значения частных переменных – членов класса;
Выполняют реальную работу объекта.
Назначение метки видимости protected – защищенный будет объяснено в лабораторной работе №5, в которой будет изучаться механизм наследования классов.
Определение класса похоже на описание типа struct. Но описание класса начинается с ключевого слова class, за которым следует имя класса (иногда его называют тегом). Формат определения класса следующий:
class < имя класса>
{
private:
< члены класса>
protected:
<члены класса>
public:
<члены класса>
} [имя объекта класса];
Рассмотрим пример определения класса. Пусть необходимо определить класс, описывающий геометрическую фигуру сфера. Для описания сферы необходимо знать ее радиус и координаты центра, тогда определение класса «Sphere» выглядит следующим образом:
class Sphere
public:
float r; // Радиус сферы
float x, y, z; // Координаторы центра сферы
;
Класс «Sphere» имеет четыре данных – члена x, y, z и r. Пока определение класса «Sphere» содержит только данные, но класс должен содержать и функции, которые этими данными манипулируют. Вернемся к рассмотренному выше примеру и перепишем определение класса «Sphere», добавив к нему несколько функций – членов.
сlass Sphere
public:
float r;
float x, y, z;
// М_РI – константа из math. h, равная pi
float Volume ( )
return (rr*r*4*M_PI/3);
float Surface _area ( )
return (rr*4*M_PI);
;
В этом новом варианте объявления класса «Sphere» имеются две функции:
- функция, которая вычисляет и возвращает объем сферы;
- функция, которая вычисляет и возвращает площадь поверхности сферы.
Функции – члены класса можно только объявить в теле класса, а определение функций поместить отдельно за классом. Для того чтобы указать, что данная функция является членом некоторого класса, необходимо связать имя функции с именем класса. Это достигается путем написания имени функции вслед за именем класса с двумя двоеточиями. Два двоеточия называются оператором расширения области видимости. Приведем новый вариант объявления класса «Sphere» , в котором содержатся только прототипы функций – членов класса, а их определения помещены ниже класса.
сlass Sphere
public:
float r;
float x, y, z;
float Volume ( ); // Объявление функции – члена класса
float Surface _area ( ); // Объявление функции – члена класса
;
float Sphere:: Volume ( ) // Определение функции
return (rr*r*4*M_PI/3);
float Sphere:: Surface _area ( ) //Определение функции
return (rr*4*M_PI);
После того, как класс определен, можно создавать переменные типа класс – объекты класса. Такие переменные объявляются там, где можно объявлять обычные переменные и с использованием такого же формата. Пример объявления:
Sphere s; // s - объект класса
Объекты класса можно объявлять и сразу после определения класса, но такой способ используется редко. Обычно класс определяется глобально, а объекты класса объявляются локально, в теле клиента класса.
После создания переменной класса можно получить доступ к открытым данным – членам и функциям – членам этого класса. Доступ к членам класса осуществляется через объект при помощи оператора «точка» (.). Этот оператор сообщает С++ о том, что нужно обеспечить доступ к членам класса, переменная которого представляет его отдельный экземпляр. Каждый экземпляр класса имеет свое множество данных, и функции – члены работают с набором данных, принадлежащим именно указанной переменной класса.
Примеры доступа:
s.x = 1.5; s.y = 2.3; s.z = 4.2; s.r = 2.0;
cout << “\n Сфера имеет координаты”<<s.x<<”, “<<s.y<<”, “<<s.z»;
cout << “\n Радиус сферы равен” <<s.r;
cout << “\n Сфера имеет объем - ”<<s. Volume ( ) ;
cout << “\n Сфера имеет площадь поверхности –“<<s. Surface _area ( );
В рассмотренном примере все члены класса «Sphere» объявлены как общие (метка public). Для реализации принципа скрытия данных данные - члены класса желательно объявлять частными, чтобы предотвратить прямой доступ к данным класса со стороны функций, не являющихся членами данного класса. В этом случае в состав класса должны входить открытые функции, которые позволяют устанавливать или получать значения закрытых переменных.
Ряд функций – членов тоже могут быть объявлены как частные, если они выполняют какую – то внутреннюю работу в классе и клиентам класса не нужно обращаться к этим функциям.
сlass Sphere
float r;
float x, y, z;
float SQR();
public:
void SetX (float xcoord);
void SetY (float ycoord);
void SetZ (float zcoord);
void SetR (float radius);
float Volume ( );
float Surface _area ( );
;
float Sphere:: SQR()
{return (r * r);
void Sphere:: SetX (float xcoord)
{ x= xcoord;}
void Sphere:: SetY (float ycoord)
{ y= ycoord;}
void Sphere:: SetZ (float zcoord)
{ z = zcoord;}
void Sphere:: SetR (float radius)
{ r= radius;}
float Sphere:: Volume ( )
return ( SQR() * r * 4 * M_PI/3);
float Sphere:: Surface _area ( )
return (SQR() * 4 * M_PI);
В этом примере в класс добавлена закрытая функция SQR(), которая вычисляет квадрат радиуса. Эта функция вызывается другими функциями этого же класса, но клиенты класса не могут ее вызвать, так как она закрыта для них. Ключевое слово private опущено, так как по умолчанию члены класса имеют закрытый доступ.
Клиентом разработанного класса является функция main(). Приведем код этой функции:
main()
{
Sphere s;
s.SetX(1.0); s.SetY(2.0); s.SetZ(3.0); s.SetR(4.0);
cout << “\n Сфера имеет объем - ”<<s. Volume ( ) ;
cout << “\n Сфера имеет площадь поверхности –“<<s. Surface _area ( );
return(0);
}
Клиент класса может объявлять не только отдельные экземпляры класса, но и массивы объектов. Объявление массивов объектов имеет такой же формат, как и объявление массива данных любого встроенного типа. Пусть функция main() объявляет массив из двух объектов класса.
main()
{
Sphere s[2];
// Работа с первым объектом
s[0].SetX(1.0); s[0].SetY(2.0); s[0].SetZ(3.0); s[0].SetR(4.0);
cout << “\n Сфера№1 имеет объем - ”<<s[0]. Volume ( ) ;
cout << “\n Сфера№1имеет площадь поверхности “<<s[0]. Surface _area ( );
// Работа со вторым объектом
s[1].SetX(1.0); s[1].SetY(2.0); s[1].SetZ(3.0); s[1].SetR(4.0);
cout << “\n Сфера№2 имеет объем - ”<<s[1]. Volume ( ) ;
cout << “\n Сфера№2 имеет площадь поверхности “<<s[1]. Surface _area ( );
return(0);
}
Клиент класса может работать с объектами, используя указатель. Обычно этот способ используется для работы с динамическими объектами или динамическими массивами объектов. В этом случае для обращения к открытым членам класса используется не оператор «точка», а оператор «стрелка».
main()
{
Sphere * ptr;
ptr = new Sphere;
ptr -> SetX(1.0); ptr -> SetY(2.0); ptr -> SetZ(3.0); ptr -> SetR(4.0);
cout << “\n Сфера имеет объем - ”<<ptr -> Volume ( ) ;
cout << “\n Сфера имеет площадь поверхности –“<<ptr ->Surface _area ( );
return(0);
}
