C++. Об’єкти класу як члени даних класу. Приклади




Об’єкти класу як члени даних класу. Приклади


Зміст


Пошук на інших ресурсах:

1. Приклад оголошення та використання об’єкту класу, який є членом-даних іншого класу

Як відомо, у класах можуть оголошуватись члени даних класу, які є об’єктами інших класів. У даному прикладі продемонстровано використання двох об’єктів, що є членами даних класу.

У прикладі оголошується 2 класи:

  • клас CMyPoint, що визначає точку з координатами x, y;
  • клас CMyLine, що визначає лінію, яка містить два об’єкти типу CMyPoint. Ці об’єкти містять координати кінців відрізка, з яких будується лінія.

Клас CMyPoint містить:

  • внутрішні члени даних x, y;
  • конструктор за замовчуванням CMyPoint();
  • методи читання внутрішніх даних класу GetX(), GetY();
  • метод SetXY(), що встановлює нові значення x, y.

Клас CMyLine містить:

  • внутрішні члени-даних класу типу CMyPoint з іменами mp1, mp2. Ці члени-даних є об’єктами класу CMyPoint. Вони визначають 2 точки, з яких складається лінія;
  • конструктор за замовчуванням CMyLine();
  • методи читання значення об’єктів mp1, mp2 які мають відповідно імена GetPoint1(), GetPoint2();
  • метод SetLine() для встановлення нового значення координат кінців відрізку CMyLine;
  • метод Length(), що обчислює довжину відрізка.

Оголошення та реалізація методів класів CMyPoint та CMyLine

// оголошення класу CMyPoint
class CMyPoint
{
    int x;
    int y;

    public:
    CMyPoint(void); // конструктор за замовчуванням

    // методи класу
    int GetX(void)
    {
        return x;
    }

    int GetY(void)
    {
        return y;
    }

    void SetXY(int nx, int ny)
    {
        x = nx; y = ny;
    }
};

// конструктор за замовчуванням
CMyPoint::CMyPoint(void)
{
    x = y = 0;
}

// ----------------------------------------------
// оголошення та реалізація методів класу CMyLine
class CMyLine
{
    CMyPoint mp1;
    CMyPoint mp2;

    public:
    // конструктор за замовчуванням
    CMyLine(void);

    // методи доступу
    CMyPoint GetPoint1(void)
    {
        return mp1;
    }

    CMyPoint GetPoint2(void)
    {
        return mp2;
    }

    void SetLine(CMyPoint p1, CMyPoint p2);

    // метод, що повертає довжину лінії
    double Length(void);
};

// реалізація методів класу CMyLine
CMyLine::CMyLine(void)
{
    mp1.SetXY(0,0);
    mp2.SetXY(1,1);
}

// встановити нові значення точок 
void CMyLine::SetLine(CMyPoint p1, CMyPoint p2)
{
    int tx, ty;
    tx = p1.GetX();
    ty = p1.GetY();
    mp1.SetXY(tx, ty);
    tx = p2.GetX();
    ty = p2.GetY();
    mp2.SetXY(tx, ty);
}

// метод, що повертає довжину лінії
double CMyLine::Length(void)
{
    int x1, y1, x2, y2;
    double len;

    x1 = mp1.GetX();
    y1 = mp1.GetY();
    x2 = mp2.GetX();
    y2 = mp2.GetY();

    len = System::Math::Sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
    return len; 
}

Демонстрація використання класу CMyLine

CMyPoint mp1, mp2;
CMyLine ml;
int d;

// виклик методів класу CPoint
// заповнення значень об'єктів mp1, mp2
mp1.SetXY(5, 8);
d = mp1.GetX(); // d = 5
mp2.SetXY(9, 11);

// виклик методів з класу CMyLine
ml.SetLine(mp1, mp2); // встановити нові значення точок

// виклик методу, що повертає першу точку з лінії
mp1 = ml.GetPoint2();

// перевірка
d = mp1.GetX(); // d = 9
d = mp1.GetY(); // d = 11

// обчислення відстані відрізка ml
// виклик методу Length
double length;
length = ml.Length(); // length = 5.0

 

2. Яким чином виконується виклик конструкторів, якщо в класі A використовується об’єкт класу B? Яким чином виділяється пам’ять для об’єктів цих класів?

Якщо в класі A оголошується об’єкт класу B, то при оголошенні об’єкту класу A конструктори обох класів викликаються у такій послідовності:

  • конструктор класу B;
  • конструктор класу A.

Таку послідовність дій компілятор формує автоматично.
Пам’ять для членів-даних класу, які є об’єктами класу, виділяється при виділенні пам’яті для класу, в якому ці об’єкти реалізовані. Тобто, якщо описати об’єкт класу A, в якому є об’єкт класу B, то пам’ять для об’єкту класу A виділяється з врахуванням (включає в себе) пам’яті об’єкту класу B.
Наприклад. Якщо взяти клас CMyPoint, що оголошений у п. 1 цієї теми, то при створенні обо’єкту класу CMyLine, спочатку викликається відповідний конструктор класу CMyPoint (виділяється пам’ять), а потім викликається конструктор класу CMyLine.

 

3. Ініціалізація внутрішнього об’єкту класу з допомогою конструктора. Приклад

Синтаксис мови C++ дозволяє проводити зручну ініціалізацію внутрішнього об’єкту класу в конструкторі з використанням символу : (двокрапка) та виклику конструктора внутрішнього класу.

Наприклад, якщо у деякому класі OuterClass оголошується екземпляр obj іншого класу InnerClass

class OuterClass
{
  ...

  // Екземпляр класу InnerClass всередині
  InnerClass obj;

  ...
}

то конструктор класу OuterClass може ініціалізувати цей об’єкт за наступним викликом

class OuterClass
{
  ...

  // Екземпляр класу InnerClass всередині
  InnerClass obj;

  // Конструктор класу OuterClass.
  // Цей конструктор отримує параметром екземпляр _obj класу InnerClass.
  // В конструкторі відбувається ініціалізація внутрішнього об'єкту obj
  // шляхом виклику obj(_obj).
  OuterClass(InnerClass _obj) : obj(_obj)
  {
    ...
  }

  ...
}

Приклад. У прикладі демонструються особливості ініціалізації внутрішніх об’єктів типу Point, які оголошуються в класі Line, а саме:

  • ініціалізація внутрішнього об’єкту в конструкторі;
  • делегування повноважень іншому конструктору.

Текст демонстраційного прикладу наступний:

#include <iostream>
using namespace std;

// Клас, що описує точку на координатній площині
class Point
{
private:
  int x, y; // внутрішні поля класу

public:
  // Конструктор без параметрів
  Point() :Point(0, 0) // делегування конструктору з двома параметрами
  { }

  // Конструктор з двома параметрами
  Point(int x, int y)
  {
    this->x = x;
    this->y = y;
  }

  // Аксесори
  int GetX() { return x; }
  int GetY() { return y; }

  void SetXY(int _x, int _y)
  {
    x = _x;
    y = _y;
  }

  // Відстань від точки до початку координат
  double Length()
  {
    return sqrt(x * x + y * y);
  }
};

// Клас, що реалізує лінію.
class Line
{
private:
  // У класі Line два внутрішні об'єкти класу Point,
  // які визначають крайні точки лінії.
  Point pt1;
  Point pt2;

public:
  // Конструктор без параметрів
  Line() : Line(pt1, pt2) // Делегування повноважень конструктору з 2 параметрами
  { }

  // Ініціалізація внутрішнього об'єкту через конструктор
  Line(Point _pt1, Point _pt2) : pt1(_pt1), pt2(_pt2)
  { }

  // Методи доступу до внутрішніх об'єктів
  Point GetP1() { return pt1; }
  Point GetP2() { return pt2; }
  void Set(Point _pt1, Point _pt2)
  {
    pt1 = _pt1;
    pt2 = _pt2;
  }

  // Метод, що визначає довжину лінії
  double Length()
  {
    int x1, y1, x2, y2;
    x1 = pt1.GetX();
    y1 = pt1.GetY();
    x2 = pt2.GetX();
    y2 = pt2.GetY();
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  }
};

void main()
{
  // Ініціалізація об'єктів у класах
  Point pt1(1, 1);
  Point pt2(3, 4);

  // Виклик конструктора з 2 параметрами класу Line
  Line ln1(pt1, pt2);

  // Вивести відстань між точками pt1, pt2
  cout << "(1,1) - (3,4) => " << ln1.Length() << endl;
}

Результат виконання програми

(1,1) - (3,4) => 3.60555

 


Зв’язані теми