§ 2. Класы

2.3. Цэлалікавы тып даных

Разгледзім прыклады выкарыстання класаў.

Прыклад 2.6. Рэалізаваць клас для апісання геаметрычнай фігуры — Figure і яго наследнікаў  круг (Circle) і трохвугольнiк (Triangle). У базавага класа трэба вызначыць агульны метад square (), які вяртае плошчу геаметрычнай фігуры, а ў наследнiкаў рэалізаваць гэты метад. Прадэманстраваць працу метадаў.

Этапы выканання задання

1. Апісаць базавы клас Figure.

    1. Базавы клас Figure з'яўляецца абстрактным класам, які будзе ўтрымліваць віртуальны метад square(). Віртуальны метад — гэта метад, які будзе перавызначаны ў класах-наследніках. Канкрэтная рэалізацыя метаду пры выкліку будзе вызначацца падчас выканання кода. У дадзеным прыкладзе выкарыстоўваецца чыстая віртуальная функцыя, якая наогул не мае вызначэння. Для таго каб апісаць такую функцыю, трэба проста прысвоіць ёй значэнне 0. Вызначаць яе будзем у класах наследніках.
    2. Абстрактны клас павінен змяшчаць віртуальны дэструктар, які дазволіць карэктна выдаляцца аб'ектам, створаным пры наследаваннi.

2. Апісаць клас наследнік Circle.

    1. Пры апісанні класа Circle трэба паказаць, што ён з'яўляецца наследнікам класа Figure. Для гэтага пасля іменi класа праз сімвал «:» пазначыць public Figure.
    2. Круг вызначаецца сваім радыусам, таму ў класе вызначана поле radius.
    3. Апісаць канструктар, які залежыць ад радыусу.
    4. Апісаць метад вылічэння плошчы. Плошча круга залежыць ад колькасці p, якая зададзена як канстанта па-за класа.

3. Апісаць клас наследнік Triangle.

    1. Пры апісанні класа Triangle трэба паказаць, што ён з'яўляецца наследнікам класа Figure. Для гэтага пасля іменi класа праз сімвал «:» пазначыць public Figure.
    2. Трохвугольнік вызначаецца даўжынямі бакоў, таму ў класе вызначаны палi a, b, c.
    3. Апісаць канструктар, які залежыць ад даўжынi бакоў.
    4. Апісаць метад вылічэння плошчы. Плошча трохвугольніка вылічаецца па формуле Герона.

Прыклад 2.7. Зададзена дата нараджэння чалавека і бягучая дата. Вызначыць колькасць поўных гадоў, якія прайшлі з дня нараджэння. Для вырашэння задачы выкарыстоўваць клас Data. Падзяліць аб'яву і вызначэнне класа, стварыўшы файлы Date.h і Date.cpp.

Этапы выканання задання

1. Клас Date быў апісаны ў прыкладзе 22.5 навучальнага дапаможніка 10-га класа ($@BOOKVIEWBYIDCH*3574*10521@$#pr5). У клас неабходна дадаць функцыі-гетэры для атрымання дня, месяца і года.

2. Дадаць файлы.

    1. Стварыць новы файл можна з дапамогай каманды File → New  Empty file.
    2. Захаваць загалоўкавы файл пад імем Date.h (h от англ. header — загаловак).
    3. Дадаць яшчэ адзін файл і захаваць яго пад імем Date.cpp.
    4. Пасля дадання файлаў зменіцца структура праекта:

    5. Шляхам перацягвання вокнаў файлы можна размясціць так, каб яны ўсе былі бачныя.

3. Загалоўкавы файл змяшчае аб'яву класа (рэалізацыю) і апісанне бібліятэк (калі яны неабходныя).

4. Файл Date.cpp змяшчае вызначэнне метадаў класа. Каб звязаць вызначэнне класа і яго рэалізацыю, неабходна ў файле рэалізацыі падключыць загалоўкавы файл з аб'явай класа: #include "Date.h". Звярніце ўвагу, што пры падключэнні яго імя файла бярэцца ў двукоссі, а не ў вуглавыя дужкі.

5. У файле main.cpp таксама неабходна падключыць загалоўкавы файл.

 

Прыклад 2.6. Праграма.

#include <iostream>

#include <cmath>

 

using namespace std;

 

double const pi = acos(-1);

 

/// базавы клас для фігур

class Figure

{

  public:

    virtual ~Figure() {}

    /// метад для вылічэння плошчы

    virtual double square() const = 0;

};

 

/// клас для круга

class Circle : public Figure

{

  private:

    double radius;

  public:

    /// канструктар ад радыусу

  Circle(double r) : radius(r) {}

    /// рэалізацыя метаду square

  double square() const {

    return radius * radius * pi;

  }

};

 

/// клас для трохвугольніка

class Triangle : public Figure

{

  private:

    double a, b, c;

  public:

    /// канструктар ад даўжынi бакоў

    Triangle(double l1, double l2, double l3) :

        a(l1), b(l2), c(l3)  {}

    /// рэалізацыя метаду square

    double square() const {

      double p = (+ b + c) / 2;

      double s = p * (- a) * 

            (- b) * (- c);

      return sqrt(s);

    }

 

    }

};

 

int main()

{

  double r;

  cout << "radius = ";

  cin >> r;

  Circle circle(r);

  cout << "S = " << circle.square() 

       << endl;

  double x, y, z;

  cout << "storony" << endl;

  cin >> x >> y >> z;

  Triangle ABC(x, y, z);

  cout << "S = " << ABC.square() << 

       endl;

    return 0;

}

Тэсціраванне:

Абстрактны клас, які змяшчае толькі віртуальныя метады, называецца інтэрфейсам. Тады абстрагаванне — гэта неабходнасць сканцэнтравацца на інтэрфейсе, не звяртаючы ўвагі на рэалізацыю.

Інтэрфейсы дазваляюць наладзіць множнае наследаванне аб'ектаў і вырашыць праблему ромбападобнага наследавання (сітуацыя, калі два класа B і C наследуюць ад A, а клас D наследуе ад абодвух класаў B і C).

Імя інтэрфейса будуецца па тых жа правілах, што і іншыя ідэнтыфікатары мовы праграмiравання. Аднак для інтэрфейсаў могуць прымяняцца дадатковыя правілы, якія дапамагаюць адрозніваць імя інтэрфейса ад імёнаў іншых элементаў праграмы. Напрыклад, у тэхналогіі COM і ва ўсіх мовах, якія падтрымліваюць яе, дзейнічае пагадненне, вынікаючы якому, імя інтэрфейса будуецца па шаблоне «I<Iмя>», гэта значыць складаецца з напісанага з загалоўнай літары асэнсаванага імені, якому папярэднічае загалоўная лацінская літара I, напрыклад IFigure.

Прыклад 2.7. Змесціва файла main.cpp.

#include <iostream>

#include <string>

#include <windows.h>

#include "Date.h"

 

using namespace std;

 

int main()

{

  SetConsoleCP(1251);

  SetConsoleOutputCP(1251);

  string s1, s2;

  cout << "Дата рождения - ";

  cin >> s1;

  cout << "Текущая дата - ";

  cin >> s2;

  Date d1(s1);

  Date d2(s2);

  int v = d2.get_Date_g() - d1.get_Date_g();

  if (d2.get_Date_m() < d1.get_Date_m())

    v --;

  else

    if (d2.get_Date_m() == d1.get_Date_m() &&

      d2.get_Date_d() < d1.get_Date_d())

        v--;

  cout << "возраст = " << v << endl;

  return 0

}

Змесціва файла Date.h.

#include <iostream>

#include <string>

#include "Date.h"

 

using namespace std;

 

Date::Date(int t_d, int t_m, int t_g)

{

    d = t_d;

    m = t_m;

    g = t_g;

}

 

Date::Date(string s)

{

   d = stoi(s.substr(0,2));

   m = stoi(s.substr(3,2));

   g = stoi(s.substr(6,4));

}

 

void Date::print()

{

cout << d << "." << m << "." << g;

}

 

string Date::get_Date_dm()

{

  string t1 = to_string(d);

  string t2 = to_string(m);

  return t1 + "." + t2;

}

 

int Date::get_Date_d()

{

    return d;

}

 

int Date::get_Date_m()

{

    return m;

}

 

int Date::get_Date_g()

{

    return g;

}