§ 2. Классы

2.1. Структура класса

 

Напомним основные понятия, связанные с описанием класса. В примере 2.1 используется класс Student.

Имя класса принято писать с заглавной буквы. В общем виде описание класса выглядит следующим образом:

class имя_класса

{

  private:

  /* список свойств и методов для 

  использования внутри класса */

  public:

  /* список методов, доступных другим 

  функциям и объектам программы */

  protected:

  /*список средств, доступных для 

  дружественных классов и наследников*/

};

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

Закрытые данные класса размещаются после модификатора доступа private. Если отсутствует модификатор public, то все функции и переменные по умолчанию являются закрытыми.

Обычно приватными делают все поля класса, а публичными — его методы. Все действия с закрытыми полями класса реализуются через его методы.

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

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

  1. При определении функции как метода класса используется значок «::»[1] для идентификации класса, которому принадлежит функция.
  2. Методы класса имеют доступ ко всем приватным компонентам своего класса.

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

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

На объекты классов, как и на объекты других типов, можно определять указатели. Затем через указатель можно обращаться к членам класса — переменным и методам (пример 2.2). Однако если при обращении через обычную переменную используется символ точка, то для обращения к членам класса через указатель применяется стрелка «–>» (знаки «минус» и «больше»).


[1] Значок обозначает операцию «раскрытие области видимости».

Пример 2.1. Программа для решения следующей задачи: «Прочитать из текстового файла данные о студентах (фамилия, город, год рождения, отметки ЦТ) и вывести в файл в порядке убывания суммарного балла фамилии, город и суммарный балл».

#include <iostream>

#include <fstream>

#include <string>

#include <windows.h>

#include <vector>

#include <algorithm>

 

using namespace std;

 

class Student

{

  private:

  /** поля для хранения фамилии

      и названия города **/

    string fam, gorod;

  /// поле - год рождения

    int god_r;

    vector <int> otm = vector<int>(3);

  public:

  /// метод для суммы отметок

    int summ();

  /// сеттеры для задания значения полей

    void set_fam(string f);

    void set_gorod(string g);

    void set_god_r(int r);

    void set_otm(vector <int> d);

  /** геттер для получения строки

     Фамилия Город Сумма баллов**/

    string get_fam_gor_summ();

};

 

int Student::summ()

{

span lang="EN-US" style="font-size: 10.0pt; font-family: 'Courier New'; color: black; mso-ansi-language: EN-US;">   int s = 0;

   for (auto i:otm)

     s += i;

   return s;

}

 

void Student::set_fam(string f)

{

    fam = f;

}

 

void Student::set_gorod(string g)

{

    gorod = g;

}

 

void Student::set_god_r(int r)

{

    god_r = r;

}

 

void Student::set_otm(vector <int> d)

{

    otm = d;

}

 

string Student::get_fam_gor_summ()

{

   string s;

   s = fam + '\t';

   s += gorod + '\t';

   s += to_string(summ());

   return s;

}

 

void vvod (vector <Student> &d)

{

  ifstream fin ("input.txt");

  int r;

  fin >> r;

  fin.ignore();

  d.resize(r);

  /** Считывание данных из файла и

      определение объектов с

      использованием сеттеров **/

  for (int i = 0; i < r; i++){

    string t_str;

    fin >> t_str;

    d[i].set_fam(t_str);

    fin >> t_str;

    d[i].set_gorod(t_str);

    int t_int;

    fin >> t_int;

    d[i].set_god_r(t_int);

    vector<int> t_vect(3);

    fin >> t_vect[0] >> t_vect[1]

        >> t_vect[2];

    d[i].set_otm(t_vect);

  }

}

 

bool comp(Student x, Student y)

{

  return (x.summ() > y.summ());

}

 

int main()

{

  SetConsoleCP(1251);

  SetConsoleOutputCP(1251);

  vector <Student> a;

  vvod (a);

  ofstream fout ("output.txt");

  sort(a.begin(),a.end(),comp);

  /** вывод данных в файл с

      использованием геттера**/

  for (int i = 0; i < a.size(); i++){

    fout << a[i].get_fam_gor_summ() << endl;

  }

  return 0;

}

Пример 2.2. Обращение через указатель к членам класса Date (пример 22.5 учебного пособия 10 класса, http://profil.adu.by/mod/book/view.php?id=3574&chapterid=10521#pr5).

Date d4("14.01.2021");

  Date *d5 = &d4;

  d5 -> set_den(17);

  d5 -> set_mesjac(3);

  cout << d4.get_Date_dm() << endl;

Изменения по указателю d5 в данном случае приведут к изменениям объекта d4. В результате выполнения команд будет выведено 17.3.