- •7. Робота з шаблонними, функціями та класами
- •7.1. Поняття про узагальнені функції
- •7.1.1. Механізм реалізації шаблонної функції з одним узагальненим типом
- •7.1.2. Безпосередньо задане перевизначення узагальненої функції
- •7.1.3. Шаблонна функція з двома узагальненими типами
- •7.1.4. Механізм перевизначення специфікації шаблону функції
- •7.1.5. Використання стандартних параметрів у шаблонних функціях
- •7.2. Поняття про узагальнені класи
- •7.1.6. Обмеження, які застосовуються при використанні узагальнених функцій
- •7.1.7. Приклад створення узагальненої функції abs()
- •7.2.1. Створення класу з одним узагальненим типом даних
- •7.2.2. Створення класу з двома узагальненими типами даних
- •7.2.3. Приклад створення узагальненого класу для організації безпечного масиву
- •7.2.4. Використання в узагальнених класах аргументів, що не є узагальненими типами
- •11.2.1. Передача покажчиком на функцію її адреси іншій функції
- •9.2.3. Класи потоків
- •9.3. Особливості механізмів перевизначення операторів введення-виведення даних
- •9.3.1. Створення перевизначених операторів виведення даних
- •9.5. Організація файлового введення-виведення даних
- •9.5.1. Відкриття та закриття файлу
- •9.5.2. Зчитування та запис текстових файлів
- •9.5.3. Неформатне введення-виведення даних у двійковому режимі
- •9.5.4. Зчитування та записування у файл блоків даних
- •10. Динамічна ідентифікація типів і оператори приведення типу
- •10.1. Динамічна ідентифікація типів
- •10.1.1. Отримання типу об'єкта у процесі виконання програми
- •10.1.2. Приклад rtti-застосування
- •11. Поняття про простори імен та інші ефективні програмні засоби
- •11.1. Особливості організації простору імен
- •11.1.1. Поняття про простори імен
- •11.1.2. Застосування настанови using
- •11.1.3. Неіменовані простори імен
- •11.1.4. Застосування простору імен std
- •11.2. Застосування покажчиків на функції
- •11.2.2. Пошук адреси перевизначеної функції
- •11.3. Поняття про статичні члени-даних класу
- •11.5. Застосування до функцій-членів класу модифікаторів const і mutable
- •11.6. Використання explicit-конструкторів
- •12. Введення в стандартну бібліотеку шаблонів
- •12.1. Огляд стандартної бібліотеки шаблонів
- •12.2. Поняття про контейнерні класи
- •12.3. Механізми роботи з векторами
- •12.3.1. Доступ до елементів вектора за допомогою ітератора
- •12.3.2. Вставлення та видалення елементів з вектора
- •12.3.3. Збереження у векторі об'єктів класу
- •12.3.4. Доцільність використання ітераторів
- •7. Робота з шаблонними, функціями та класами 1
- •7.1. Поняття про узагальнені функції 1
- •10. Динамічна ідентифікація типів і оператори приведення типу 26
- •11. Поняття про простори імен та інші ефективні програмні засоби 31
- •12. Введення в стандартну бібліотеку шаблонів 44
11.3. Поняття про статичні члени-даних класу
Ключове слово static можна застосовувати і до членів-даних класу. Оголошуючи член-даних класу статичним, ми тим самим повідомляємо компілятор про те, що, незалежно від того, скільки об'єктів цього класу буде створено, існує тільки одна копія цього static-члена. Іншими словами, static-член розділяється між всіма об'єктами класу. Всі статичні дані під час першого створення об'єкта ініціалізуються нульовими значеннями, якщо перед цим не представлено інших значень ініціалізації.
Під час оголошення статичного члена-даних у класі програміст не повинен його визначати. Необхідно забезпечити його глобальне визначення поза цим класом. Це реалізується шляхом повторного оголошення цієї статичної змінної за допомогою оператора дозволу області видимості, який дає змогу ідентифікувати, до якого класу вона належить. Тільки у цьому випадку для цієї статичної змінної буде виділено пам'ять.
Розглянемо приклад використання static-члена класу. Вивчіть код цієї програми і постарайтеся зрозуміти, як вона працює.
Демонстрація механізму використання статичних членів-даних класу
#include <vcl>
#include <iostream> // Для потокового введення-виведення
#include <conio> // Для консольного режиму роботи
using namespace std; // Використання стандартного простору імен
class ShareVar {
static int n;
public:
void Set(int c) { n = c; }
void Show() { cout << n << " "; }
};
int ShareVar::n; // Визначаємо static-член n
int main()
{
ShareVar ObjA, ObjB;
ObjA.Show(); // Виводиться 0
ObjB.Show(); // Виводиться 0
ObjA.Set(10); // Встановлюємо static-члена n дорівнює 10
ObjA.Show(); // Виводиться 10
ObjB.Show(); // Також виводиться 10
getch(); return 0;
}
Зверніть увагу на те, що статичний цілочисельний член n оголошений і у класі ShareVar, і його визначено як глобальна змінна. Як було сказано вище, необхідність такого подвійного оголошення зумовлена тим, що під час оголошення члена n у класі ShareVar пам'ять для нього не виділяється. Компілятор C++ ініціалізував змінну n значенням 0, оскільки ніякої іншої ініціалізації у програмі немає. Тому внаслідок двох перших викликів функції Show() для об'єктів ObjA і ObjB відображається значення 0. Потім об'єкт ObjA встановлює члену n значення, яке дорівнює 10, після чого об'єкти ObjA і ObjB знову виводять на екран його значення за допомогою функції Show(). Але оскільки існує тільки одна копія змінної n, що розділяється об'єктами ObjA і ObjB, то значення 10 буде виведено під час виклику функції Show() для обох об'єктів.
Якщо static-змінна є відкритою (тобто public-змінною), до неї можна звертатися безпосередньо через ім'я її класу, без посилання на будь-який конкретний об'-єкт. Розглянемо, наприклад, таку версію класу ShareVar:
class ShareVar {
public:
static int n;
void Set(int c) { n = c; };
void Show() { cout << n << " "; }
};
У даній версії змінна n є public-членом даних класу. Це дає змогу нам звертатися до неї безпосередньо, як це показано в такій настанові:
ShareVar::n = 100;
У цьому записі значення змінної n встановлюється незалежно від об'єкта, а для звернення до неї достатньо використовувати ім'я класу і оператора дозволу області видимості. Більше того, ця настанова є правомірною навіть для створення якихнебудь об'єктів типу ShareVar. Таким чином, отримати або встановити значення staticчлена класу можна до того, як будуть створені будь-які об'єкти.
І хоча Ви, можливо, поки що не відчули потреби в static-членах класу, проте, у міру набуття досвіду програмування мовою C++, Вам доведеться наштовхнутися на ситуацію, коли вони виявляться дуже корисними, тобто дадуть змогу уникнути застосування глобальних змінних.
Можна також оголосити статичною і функцію-члена класу, але це непоширена практика. До статичної функції-члена класу можуть отримати доступ тільки інші static-члени цього класу2. Статична функція-член не має покажчика this. Створення віртуальних статичних функцій-членів класу не дозволяється. Окрім цього, їх не можна оголошувати з модифікаторами const або volatile. Статичну функцію-члена можна викликати для об'єкта її класу або незалежно від будь-якого об'єкта, а для звернення до неї достатньо використовувати ім'я класу і оператор дозволу області видимості.
