КИТ и Э КБГУ Понедельник, 06.05.2024, 16:16
Приветствую Вас Гость | RSS
Меню сайта

Наш опрос
Оцените мой сайт
Всего ответов: 118

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Классы

  1. Определение класса. Объекты классов. Функции-члены класса. Спецификаторы доступа.
  2. Конструктор класса. Деструктор класса. Друзья класса. Вложенные классы.
  3. Шаблоны классов. Определение шаблона класса. Функции-члены шаблонов классов. Объявления друзей в шаблонах классов.

          Практическая работа 11. Разработка пользовательских классов.

 

Определение класса. Объекты классов. Функции-члены класса. Спецификаторы доступа.

1. Определение класса

Класс - это пользовательский тип.

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

Можно сказать, что класс это реализация абстрактного типа данных в языке программирования С++.

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

Данные класса также называются его атрибутами, а функции методами. Набор функций класса называется его интерфейсом.

Синтаксически, класс определяется следующим образом:

class|struct|union имя_класса

{

// члены класса

};

При определении класса должно использоваться только одно из ключевых слов class, struct или union. Каждое из этих ключевых слов устанавливает различные режимы доступа к членам класса.

При использовании ключевого слова class доступ ко всем членам класса закрыт, а при использовании ключевых слов struct и union– открыт.

Чтобы открыть или закрыть доступ клиентов к определенным членам класса используются спецификаторы доступа.

Пример 1. Определим интерфейс контейнерного класса для хранения одного целого числа.

struct IntBox

{

// атрибуты класса

bool empty;                              // состояние контейнера

int room;                                  // место для хранения целого числа

// методы класса

void put(int n);                         // положить целое число в контейнер

int get();                                    // извлечь целое число из контейнера

bool isEmpty();                        // проверить, свободен ли контейнер

};

 

Как правило, интерфейс класса помещается в отдельный заголовочный файл, который называется также как и класс. В нашем случае интерфейс класса нужно поместить в заголовочный файл IntBox.h

 

2. Определение функций-членов класса

Функции-члены класса определяются как обычные функции. Но, для того чтобы показать, что эти функции принадлежат классу, нужно перед именем функции записать имя класса и оператор разрешения области видимости.

Определение класса вводит область видимости, которой принадлежат имена членов класса. Определение функции-члена класса также принадлежит области видимости класса. Отсюда следует, что в теле функции-члене класса можно обращаться к другим членам этого класса просто по имени.

Пример 2. Определим функции, члены класса IntBox:

void IntBox::put(int n)

{

room = n;

empty = false;

}

int IntBox::get()

{

empty = true;

return room;

}

bool IntBox::isEmpty()

{  return empty;  }

 

Как правило реализация функций также помещается в отдельный файл, назвать который можно IntBox.cpp

Функция, член класса, также может быть определена внутри класса. В этом случае функция, член класса, считается встроенной.

Пример 3. Функцию isEmpty определим внутри класса

struct IntBox

{

. . .

bool isEmpty() { return empty; }

};

 

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

struct date { int month, day, year; };

date today;

void set_date(date*, int, int, int);

void next_date(date*);

void print_date(const date*);

 

Никакой явной связи между функциями и структурой date нет. Ее можно установить, если описать функции как члены структуры:

struct date {

int month, day, year;

void set(int, int, int);

void get(int*, int* int*);

void next();

void print();

};

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

date today;

date my_birthday;

void f()

{

my_birthday.set(30,12,1950);

today.set(18,1,1991);

my_birthday.print();

today.next();

}

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

class date {

int month, day, year;

public:

void set(int, int, int);

void get(int*, int*, int*);

void next();

void print()

};

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

void date::print() // печать даты в принятом в США виде

{

cout << month << '/' << day << '/' << year ;

}

Однако от функций не членов частные члены класса date уже ограждены:

void backdate()

{

today.day--;                                       // ошибка

}

Есть ряд преимуществ в том, что доступ к структуре данных ограничен явно указанным списком функций. Любая ошибка в дате (например, December, 36, 1985) могла быть внесена только функцией-членом, поэтому первая стадия отладки - локализация ошибки – происходит даже до первого пуска программы. Это только частный случай общего правила: любое изменение в поведении типа date может и должно вызываться изменениями в его членах. Другое преимущество в том, что потенциальному пользователю класса для работы с ним достаточно знать только определения функций-членов.

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

Можно описать функцию-член таким образом, что объект, для которого она вызывается, будет доступен ей только по чтению. Тот факт, что функция не будет изменять объект, для которого она вызывается, обозначается служебным словом const в конце списка параметров:

 

class X {

int m;

public:

readme() const { return m; }

writeme(int i) { m = i; }

};

Функцию-член со спецификацией const можно вызывать для постоянных объектов, а функцию-член без такой спецификации - нельзя:

void f(X& mutable, const X& constant)

{

mutable.readme(); // нормально

mutable.writeme(7); // нормально

constant.readme(); // нормально

constant.writeme(7); // ошибка

}

 

3. Доступ к членам класса

Доступ к членам класса внутри области видимости этого класса выполняется по их именам. При доступе к членам класса вне области видимости этого класса используются операторы (.) и (->), как и в случае доступа к членам структуры.

К любому члену класса, принадлежащему текущему объекту, можно также обратиться через указатель this.

Например, для класса IntBox можно написать

this -> empty = false;

Но, так как функции-члены класса имеют доступ ко всем членам класса по умолчанию, то указатель this используется в основном для возврата указателя или ссылки на объект, к которому применяется функция-член класса.

После определения класса можно объявлять переменные, которые имеют тип этого класса, или другими словами принадлежат этому классу или являются экземплярами этого класса.

В языке программирования С++ экземпляры класса называются объектами.

Над объектами можно выполнять функции, определенные в классе.

 

Пример 5. Работа с объектами типа IntBox.

#include <iostream>

#include "IntBox.h"

using namespace std;

int main()

{

IntBox box = {true};                         // объявление объекта типаIntBox

int n;

if (box.isEmpty())

box.put(10);

if (!box.isEmpty())

n = box.get();

cout << n <<endl;                              // печатает10

return 0;

}

Здесь предполагается, что интерфейс класса IntBox определен в заголовочном файле IntBox.h.

4. Спецификаторы доступа

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

Все члены класса, объявленные после метки public и расположенные до следующей метки, доступны как в классе, так и вне этого класса.

Все члены класса, объявленные после метки protected и расположенные до следующей метки, доступны в классе и в наследниках этого класса.

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

По умолчанию все члены класса, объявленного с помощью ключевого слова class, имеют спецификацию доступа private, а объявленные с помощью ключевых слов structure или union– спецификацию доступа public.

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

class IntBox

{

bool empty;                                       // состояние контейнера

int room;                                                     // место для хранения целого числа

public:

IntBox();                                                     // конструктор

void put(int n);                                            // положить целое число в контейнер

int get();                                                      // взять целое число из контейнера

bool isEmpty();                                           // проверить, свободно ли место

};

Но в этом случае в классе должна быть определена функция для инициализации объектов этого класса. Такая функция называется конструктором и имеет такое же имя, как и сам класс. В нашем случае это функция IntBox, которая имеет следующее определение:

IntBox::IntBox() { empty = true; }

 

Задание 1

Реализовать класс Student, который имеет следующий интерфейс:

class Student

{

char name[10];                                                     // фамилия студента

int num;                                                      // номер группы

double grade;                                                        // средний бал

public:

// конструкторы

Student();                                                    // конструктор по умолчанию

Student(const char* _name, const int& _num, const double& grade);

void setName(const char* _name);

void getName(char* _name);

bool changeName(const char* oldName, const char* newName);

void setNum(const int& _num);

int getNum();

bool changeNum(const int& oldNum, const int& newNum);

void setGrade(const double& _grade);

double getGrade();

bool changeGrade(const double& oldGrade, const double& newGrade);

 

// функции для ввод-вывода данных в объект типа Student

void input(istream& in);

void output(ostream& out);

};

Определение класса поместить в заголовочный файл student.h, а реализацию функций-членов класса – в файл student.cpp. Для проверки работоспособности класса Student написать тестирующую программу, в которой вызываются все методы класса.

Вход на сайт

Поиск

Календарь
«  Май 2024  »
ПнВтСрЧтПтСбВс
  12345
6789101112
13141516171819
20212223242526
2728293031

Архив записей

Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz

  • Copyright Fatima_Zh © 2024Бесплатный хостинг uCoz