C++. Класи. Види функцій-членів класу. Звичайні функції-члени. Статичні (static) функції-члени. Приклади використання
Дана тема базується на використанні функцій-членів класу, орієнтованих на компілятор Visual C++. У реалізаціях компіляторів різних розробників можуть бути суттєві відмінності, особливо що стосується статичних функцій-членів.
Зміст
- 1. Які види функцій-членів можна оголошувати в класах?
- 2. Приклад оголошення класу, що містить функції-члени, які не використовують додаткових ключових слів
- 3. Приклад оголошення класу, що містить статичні (static) функції-члени
- 4. Яка відмінність статичних функцій-членів від звичайних функцій-членів
- 5. У яких випадках доцільно застосовувати статичні (static) функції-члени класу
- Зв’язані теми
Пошук на інших ресурсах:
1. Які види функцій-членів можна оголошувати в класах?
У класах можна оголошувати такі види функцій:
- “звичайні” функції-члени. Це функції, в оголошенні яких не використовуються додаткові ключові слова (const, volatile, static);
- статичні функції. Це функції, які оголошені з ключовим словом static;
- константні функції. Це функції, які оголошені з ключовим словом const;
- функції-члени, що повертають непостійний об’єкт. Це функції, які оголошені з ключовим словом volatile;
- функції-члени з константним покажчиком this;
- функції-члени з непостійним покажчиком this;
- вбудовані функції-члени (inline).
2. Приклад оголошення класу, що містить функції-члени, які не використовують додаткових ключових слів
У даному прикладі оголошено клас CLine, що описує лінію на координатній площині. Лінія складається з координат точок (x1; y1), (x2; y2). Клас містить прості функції члени, які оголошені в розділі public (загальнодоступні). З допомогою цих функцій-членів здійснюється читання/модифікація внутрішніх змінних класу.
// клас, що описує лінію на координатній площині class CLine { int x1, y1; int x2, y2; public: CLine(void); ~CLine(void); // методи класу void SetLine(int nx1, int ny1, int nx2, int ny2); int GetX1(void) { return x1; } int GetY1(void) { return y1; } int GetX2(void) { return x2; } int GetY2(void) { return y2; } }; // Реалізація методів класу // конструктор за замовчуванням CLine::CLine(void) { x1 = y1 = 0; x2 = y2 = 1; } // деструктор CLine::~CLine(void) { } // реалізація простої функції-члена класу void CLine::SetLine(int nx1, int ny1, int nx2, int ny2) { x1 = nx1; y1 = ny1; x2 = nx2; y2 = ny2; }
Використання класу в іншому програмному коді
// оголошення об'єкту класу CLine CLine CL; int t; // виклик функцій-членів класу CL.SetLine(5, 6, 10, 20); t = CL.GetX2(); // t = 10 t = CL.GetY1(); // t = 6
3. Приклад оголошення класу, що містить статичні (static) функції-члени
У даному прикладі оголошено клас CCircle, що описує коло на координатній площині. Клас реалізує такі внутрішні члени даних та методи:
- внутрішні змінні (члени) класу x, y, r (координати центру та радіус кола);
- конструктор класу CCircle(), який визначає одиничне коло (r=1) з центром на початку координат;
- статичну функцію-член класу SetData1(), яка встановлює значення глобальних змінних xx, yy, rr оголошених за межами класу;
- звичайну (нестатичну) функцію-член класу SetData2(), яка змінює значення внутрішніх змінних x, y, r класу;
- звичайні (нестатичні) методи класу, що читають значення внутрішніх змінних класу x, y, r та глобальних змінних xx, yy, rr.
// клас, що описує коло на координатній площині class CCircle { // внутрішні змінні класу int x, y; // координати центру кола int r; // радіус кола public: // конструктор класу CCircle(void); // статичний метод класу - тільки для глобальних змінних static void SetData1(int nx, int ny, int nr); // звичайні (нестатичні) методи класу // встановити нові значення внутрішніх змінних класу void SetData2(int nx, int ny, int nr); // зчитати значення внутрішніх змінних класу int GetX(void) { return x; } int GetY(void) { return y; } int GetR(void) { return r; } // зчитати значення глобальних змінних класу int GetXX(void); int GetYY(void); int GetRR(void); }; // глобальні змінні int xx, yy, rr; // ці змінні може змінювати статична функція-член класу // конструктор класу CCircle::CCircle(void) { // заповнення значень внутрішніх (локальних) змінних x = 0; y = 0; r = 1; } // статична функція-член класу void CCircle::SetData1(int nx, int ny, int nr) { // присвоювання значень глобальним змінним, // що оголошені поза межами класу xx = nx; yy = ny; rr = nr; // працювати з внутрішніми змінними класу у статичній функції заборонено // x = nx; // Заборонено! Помилка: "... illegal reference to non-static member 'CCircle::x' // y = ny; // також заборонено } // встановити нові значення звичайних (нестатичних) методів класу void CCircle::SetData2(int nx, int ny, int nr) { x = nx; y = ny; r = nr; } // зчитати значення глобальних змінних класу int CCircle::GetXX(void) { return xx; } int CCircle::GetYY(void) { return yy; } int CCircle::GetRR(void) { return rr; }
Змінювати значення внутрішніх змінних класу зі статичної функції-члена класу заборонено. Якщо у функції SetData1() спробувати змінити значення внутрішніх змінних класу x, y
void CCircle::SetData1(int nx, int ny, int nr) { ... x = nx; y = ny; ... }
то компілятор видасть помилку
... illegal reference to non-static member 'CCircle::x'
Якщо потрібно змінити значення внутрішніх змінних класу зі статичної функції-члена, тоді цій функції потрібно передати покажчик this класу.
Нижченаведений програмний код демонструє використання статичної функції-члена для класу Circle
// використання класу CCircle CCircle C1; int tx, ty, tr; // додаткові змінні // виклик статичної функції-члена C1.SetData1(2, 3, 4); // змінюються тільки глобальні змінні xx, yy, rr // прочитати значення внутрішніх змінних класу tx = C1.GetX(); // tx = 0 - внутрішні змінні x,y,r ініціалізовані конструктором класу tr = C1.GetR(); // tr = 1 // прочитати значення глобальних змінних, що оголошені за межами класу tx = C1.GetXX(); // tx = 2 ty = C1.GetYY(); // ty = 3 // виклик звичайної (нестатичної) функції-члена класу C1.SetData2(2, 3, 4); // змінюються тільки внутрішні змінні x, y, r tx = C1.GetX(); // tx = 2 tr = C1.GetR(); // tr = 4 // інший спосіб виклику статичної функції-члена CCircle::SetData1(7, 8, 9); tx = C1.GetXX(); // tx = 7 ty = C1.GetYY(); // ty = 8
4. Яка відмінність статичних функцій-членів від звичайних функцій-членів
Основні відмінності статичних функцій-членів від звичайних:
- викликати статичну функцію-член можна без посилання на об’єкт класу, наприклад CMyClass::MyStaticFuntion(…). У цьому випадку використовується оператор розширення області видимості ‘::’;
- статичні функції-члени не отримують покажчика this класу. Це означає, що вони не можуть отримати доступ до членів даних класу (за винятком членів-даних класу, які оголошені як статичні – з ключовим словом static);
- у C++ статична функція-член класу є глобальною. Тому її доцільно використовувати для зміни значень глобальних змінних, які оголошені за межами класу але мають застосування в класі.
5. У яких випадках доцільно застосовувати статичні (static) функції-члени класу
Статичні функції-члени класу доцільно застосовувати у випадках, коли в класі потрібно використовувати глобальні змінні, що є спільними для різних об’єктів (екземплярів) цього класу.
Зв’язані теми
- Опис функції. Фактичні та формальні параметри. Передача параметрів у функцію за значенням та за адресою
- Функції і масиви. Передача одновимірного та багатовимірного масиву в функцію. Передача структури і класу в функцію