Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛР20-С++-16-сентября-2012 (1).doc
Скачиваний:
33
Добавлен:
12.11.2019
Размер:
1.18 Mб
Скачать

1.6. Синтаксис объявления класса

Класс - фундаментальное понятие С++, он лежит в основе многих свойств С++. Класс предоставляет механизм для создания объектов. В классе отражены важнейшие концепции объектно-ориентированного программирования: инкапсуляция, наследование, полиморфизм.

С точки зрения синтаксиса, класс в С++ - это структурированный тип, образованный на основе уже существующих типов.

В этом смысле класс является расширением понятия структуры. В простейшем случае класс можно определить с помощью конструкции:

тип_класса имя_класса{список_членов_класса};

где

тип_класса – одно из служебных слов class, struct, union;

имя_класса – идентификатор;

список_членов_класса – определения и описания типизированных данных и принадлежащих классу функций.

Функции – это методы класса, определяющие операции над объектом.

Данные – это поля объекта, образующие его структуру. Значения полей определяет состояние объекта.

Пример 20.1.

struct date // дата

{int month,day,year; // поля: месяц, день, год

void set(int,int,int); // метод – установить дату

void get(int*,int*,int*); // метод – получить дату

void next(); // метод – установить следующую дату

void print(); // метод – вывести дату

};

Пример 20.2.

struct class complex // комплексное число

{double re,im;

double real(){return(re);}

double imag(){return(im);}

void set(double x,double y){re = x; im = y;}

void print(){cout<<“re = “<<re; cout<<“im = “<<im;}

};

Синтаксис объявления класса, который не является наследником никакого другого класса:

class Имя_Класса

{

спецификатор доступа:

данные и функции

спецификатор доступа:

данные и функции

спецификатор доступа:

данные и функции

};

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

Для изменения видимости (доступности) компонент в определении класса можно использовать спецификаторы доступа: public, private, protected. Члены класса объявляются в одном из трех разделов класса: public, private, protected. Включение члена класса в тот или иной раздел влияет на доступность этого члена для объектов других классов.

Имеются 3 спецификатора доступа:

Public (общий) – члены класса будут доступны как в классе, так и в любой точке программы внутри области видимости класса, к которому они относятся. Это внешняя часть класса, или интерфейс его взаимодействия с другими классами.

Доступ извне осуществляется через имя объекта:

имя_объекта.имя_члена_класса

ссылка_на_объект.имя_члена_класса

указатель_на_объект->имя_члена_класса

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

Protected (защищенный) – члены класса будут доступны только внутри класса и внутри потомков класса. Раздел protected позволяет, используя механизм наследования, передавать включенные в него члены класса по наследству.

В классе элементы по умолчанию являются закрытыми.

Действие спецификатора доступа распространяется до следующего спецификатора или до конца описания класса.

По умолчанию, все члены класса, объявленные после ключевого слова class до первого спецификатора доступа имеют спецификацию доступа private.

Пример 20.3.

class complex

{

double re, im; // private по умолчанию

public:

double real(){return re;}

double imag(){return im;}

void set(double x,double y){re = x; im = y;}

};

Класс есть расширение понятия структуры языка С++. Он позволяет создавать типы и определять функции, которые задают поведение типа. Каждый представитель класса называется объектом.

Определение класса:

  • Определение класса идентично определению структуры в С++, за исключением того, что

  • оно обычно содержит одну или несколько спецификаций доступа (public, protected, private);

  • вместо ключевого слова struct используется слово class;

  • оно обычно включает в себя функции (функции-элементы или методы) наряду с данными-элементами;

  • обычно в нем имеются некоторые специальные функции, такие как конструктор (функция с тем же именем, что и сам класс) и деструктор (функция, именем которой является имя класса с префиксом - тильдой (~)).

Пример 20.4. Определение класса.

class str

{ char *s; //элемент-данное

public: //спецификатор открытого доступа

str(char *word); //функция-элемент: конструктор

~str(); //функция-элемент: деструктор

void write(); //функция-элемент: метод печати

};

Класс — это такой «тип данных», который представляет собой объединение полей (аналогично структуре) и функций (подпрограмм). Функции, принадлежащие классу называются методами. Общий вид описания класса похож на описание структуры

class ИмяКласса {

Тип1 Имя1;

Тип2 Имя2;

...

Функция1

Функция2

...

}; //.

Поскольку C++ – объектно-ориентированный язык, он позволяет использовать при разработке программ как готовые классы, доступные через соответствующие библиотеки, так и классы, разработанные пользователем.

Рассмотрим создание класса пользователем и применение класса, созданного пользователем, в программе.

Объявление класса:

class <имя класса>

{

public:

<объявление переменных, констант, функций>

private:

<объявление переменных, констант, функций>

protected:

<объявление переменных, констант, функций>

};

Объявление класса начинается с ключевого слова class. Переменные, константы, функции, включенные в класс, называются членами класса.

Пример 20.5.

В качестве примера опишем класс для работы с комплексными числами. Комплексное число состоит из двух компонент — действительной и мнимой частей. Значит классдолжен как минимум содержать два поля типа float

class CComplex {

public :

float x;

float y;

}; //.

Пример 20.5.

Однако, определение, приведенное в примере 20.5, ничем не отличается от структуры. Расширим класс двумя методами для вычисления модуля и аргумента комплексного числа.

class CComplex {

public :

float x;

float y;

float Modul(void)

{return sqrt(x*x+y*y);}

float Argum(void)

{if (x==0) return 3.14159/2;

else return atan(y/x);}

}; //.

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

Пример 20.6.

class CComplex {

public:

float x;

float y;

float Modul(void);

float Argum(void);

};

И оно размещяется в заголовочном файле complex.h. Реализацию методов можно разместить в отдельном файле complex.cpp и оформить следующим образом:

#include "complex.h"

float CComplex::Modul(void)

{return sqrt(x*x+y*y);}

float CComplex::Argum(void)

{if (x==0) return 3.14159/2;

else return atan(y/x);} //.

Также как при объявлении структуры, определение класса не приводит к выделению памяти. Оно является описанием нового типа, который вместе с данными обладает подпрограммами их обработки. Переменные этого типа называются объектами. Создадим объект с именем А, представляющий собой комплексное число

CComplex A; //.

Объект — это переменная типа класс. Такая терминология используется не случайно. Объекто-ориентированная технология программирования позволяет строить модели реальных объектов, а также выстраивать их иерархии с помощью наследования свойств одних объектов их наследниками. В этой связи полезно вспомнить известную из биологии классификацию животных. Так, например, класс млекопитающих обладает некоторыми свойствами, присущими абслютно всем его представителям. Вместе с тем среди млекопитающих выделяют отряд хищных. Они вдобавок имют свои свойства. Среди хищных имеется семейство медвежьих со своими свойствами. Таким образом, «конкретный экземпляр» медведь бурый обладает свойствами всех перечисленных уровней классификации. Другими словами, каждый следующий уровень классификации добавляет свои свойства. Медведь бурый является аналогом объекта, а уровни классификации — это классы со структурой наследования.

Пример 20.7.

Рассмотрим в качестве примера класс принтеров. Включим в его состав следующие свойства: модель, год выпуска и состояние принтера; спрячем эти свойства от постороннего воздействия, поместив в раздел private. Ограничимся двумя возможными состояниями принтера: 0 – принтер готов к работе, 1 – принтер печатает. Методы сделаем доступными для других объектов. Метод init_printer() позволит установить начальные значения свойствам принтера. Метод set_print() переведет принтер в состояние печати, если принтер до того находился в состоянии готовности, и не изменит его состояния, если принтер уже печатал. Метод stop_print() приводит к остановке печати. Метод show() отображает состояние принтера на экране:

class Printer

{

private:

char model[15]; //модель принтера

int year; //год выпуска

int status; //состояние принтера

public:

void init_printer(char* _model, int _year);

void set_print();

void stop_print();

void show();

};

Замечание. Если раздел private включен в объявлении класса первым, ключевое слово private можно опустить:

class Printer

{

char model[15]; //модель принтера

int year; //год выпуска

int status; //состояние принтера

public:

void init_printer(char*_model,int_year);

void set_print();

void stop_print();

void show();

};

Описание методов:

void Printer::init_printer(char* _model,int _year)

{

strcpy(model,_model); //инициализация свойства model

year=_year; //инициализация свойства year

status=0; //начальное состояние – готов к печати

}

 

void Printer :: set_print()

{

if (!status) status=1;

}

 

void Printer :: stop_print()

{

status = 0;

}

void Printer :: show()

{

cout<<"Model:"<<model<<"year:"<<year<<"status:"<<status<<endl;

}

В главную часть программы – функцию main() – включим следующие действия: создание объекта, инициализация свойств объекта, изменение состояния объекта и вывод его текущего состояния на экран:

int main(void)

{

Printer printer; //создание объекта

//инициализация свойств объекта

printer.init_printer("HP5P", 2004);

printer.show(); //вызов метода объекта

printer.set_print();

printer.show();

printer.set_print();

printer.show();

printer.stop_print();

printer.show();

return 0;

}

Полный текст программы для примера 20.7:

//Пример 20.7

#include <iostream.h>

#include <conio.h>

class Printer

{

private:

char model[15]; //модель принтера

int year; //год выпуска

int status; //состояние принтера

public:

void init_printer(char* _model, int _year);

void set_print();

void stop_print();

void show();

};

void Printer::init_printer(char* _model,int _year)

{

strcpy(model,_model); //инициализация свойства model

year=_year; //инициализация свойства year

status=0; //начальное состояние - готов к печати

}

void Printer :: set_print()

{

if (!status) status=1;

}

void Printer :: stop_print()

{

status = 0;

}

void Printer :: show()

{

cout<<"Model: "<<model<<" year: "<<year<<" status: "<<status<<endl;

}

int main()

{

Printer printer; //создание объекта

//инициализация свойств объекта

printer.init_printer("HP5P", 2004);

printer.show(); //вызов метода объекта

printer.set_print();

printer.show();

printer.set_print();

printer.show();

printer.stop_print();

printer.show();

cout << "\nНажмите любую клавишу..." ;

getch();

return 0;

}

В результате работы программы на экране появятся 4 строки текста:

Model: HP5P year: 2004 status: 0,

Model: HP5P year: 2004 status: 1,

Model: HP5P year: 2004 status: 1,

Model: HP5P year: 2004 status: 0.