Об’єкти класу як члени даних класу. Приклади
Зміст
- 1. Приклад оголошення та використання об’єкту класу, який є членом-даних іншого класу
- 2. Яким чином виконується виклик конструкторів, якщо в класі A використовується об’єкт класу B? Яким чином виділяється пам’ять для об’єктів цих класів?
- 3. Ініціалізація внутрішнього об’єкту класу з допомогою конструктора. Приклад
- Зв’язані теми
Пошук на інших ресурсах:
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
⇑
Зв’язані теми
- Посилання на об’єкт класу. Доступ до об’єкту класу за посиланням. Посилання як члени даних класу. Приклади
- Використання членів даних класу. Статичні (static) члени даних в класі. Статичні члени даних для native-класів та managed-класів в середовищі CLR
- Поняття класу. Оголошення класу. Об’єк класу. Класи в середовищі CLR. Інкапсуляція даних в класі
- Конструктор класу. Конструктор за замовчуванням. Параметризовані конструктори. Приклади класів, що містять конструктори