C++. Класи. Частина 3. Використання членів даних класу. Статичні (static) члени даних в класі. Статичні члени даних для native-класів та managed-класів в середовищі CLR
Зміст
- 1. Які види доступу можуть застосовуватись до даних?
- 2. Чи можна ініціалізувати дані всередині класу при їх оголошенні?
- 3. Як оголосити статичний член даних в native-класі? Приклад оголошення та використання
- 4. Яке правило діє щодо використання статичного члену класу екземплярами цього класу?
- 5. В якій області пам’яті розподіляється статичний член даних?
- 6. Скільки разів виділяється пам’ять для статичного члена даних?
- 7. Чи можна ініціалізувати статичний член класу при його оголошенні в native-класі?
- 8. Як оголосити статичний член даних у managed-класі? Приклад оголошення та використання
- 9. Які є способи доступу до загальнодоступних (public) статичних членів даних?
- 10. Приклад використання загальнодоступного статичного члена для native-класу
- 11. Приклад використання загальнодоступного статичного члена для managed-класу
- 12. Для чого потрібні статичні члени даних? Переваги використання статичних членів даних
- 13. Які є способи доступу до прихованих статичних членів класу (оголошених в розділі private)?
- Зв’язані теми
Пошук на інших ресурсах:
1. Які види доступу можуть застосовуватись до даних?
Дані і методи класу є членами класу. Під час оголошення даних можна застосовувати усі відомі способи доступу. Дані можуть бути оголошені як: приватні (private), захищені (protected), загальнодоступні (public).
Більш детально про види доступу описується в темі:
2. Чи можна ініціалізувати дані всередині класу при їх оголошенні?
Під час оголошення дані ініціалізувати не можна. Ініціалізувати дані можна в методах класу, конструкторах класу, зовнішніх методах тощо. Клас – це не об‘єкт, і пам‘ять під нього не виділяється до тих пір, поки не буде створено екземпляру (об‘єкту) класу.
Дані в класі подібні полям структури.
3. Як оголосити статичний член даних в native-класі? Приклад оголошення та використання
Статичний член даних в класі оголошується з допомогою ключового слова static. Оскільки, це є статичний член даних, то потрібно його визначити (описати змінну) за межами класу. Доступ до цього статичного члена даних мають усі екземпляри (об’єкти) класу.
Щоб використовувати статичний член даних у класі, потрібно:
- оголосити статичний член даних у тілі класу (у будь-якому розділі класу);
- визначити статичний член даних за межами класу.
Приклад. У native-класі (unmanaged-класі) CMyClass оголошується статичний член даних з іменем d цілого типу.
// оголошення native-класу class CMyClass { static int d; // статичний член даних - тільки оголошення public: CMyClass(void); // конструктор ~CMyClass(void); // деструктор // методи доступу до статичного члена даних int Get(void) { return d; } void Set(int nd) { d = nd; } }; // визначення статичного члена даних за межами класу int CMyClass::d; // виділяється пам’ять // явно заданий конструктор за замовчуванням CMyClass::CMyClass(void) { d = 0; } // деструктор CMyClass::~CMyClass(void) { }
Як видно з вищенаведеного коду, з допомогою оператора розширення доступу ‘::’ відбувається визначення статичного члена даних.
Використання статичного члена d, оголошеного в класі CMyClass з іншого методу (програмного коду):
// використання статичного члена класу CMyClass MC1; // об'єкт (екземпляр) класу 1 CMyClass MC2; // об'єкт (екземпляр) класу 2 MC2.Set(25); int t; t = MC1.Get(); // t = 25 - обидва об'єкти мають доступ до однієї і тієї ділянки пам'яті
4. Яке правило діє щодо використання статичного члену класу екземплярами цього класу?
Якщо в класі оголошено статичний член, то усі екземпляри (об’єкти) класу розділяють цей статичний член класу. Точніше кажучи, цей статичний член класу є спільним для усіх об’єктів цього класу. На відміну від автоматичних даних (даних без слова static), не може створюватись декількох копій статичних даних.
5. В якій області пам’яті розподіляється статичний член даних?
Статичний член даних розподіляється у фіксованій області даних. Це відбувається на стадії компоновки.
6. Скільки разів виділяється пам’ять для статичного члена даних?
Пам’ять для статичного члена даних виділяється на стадії компоновки тільки один раз в той момент, коли визначається статичний елемент. У прикладі вище (п. 3) пам’ять виділяється у рядку
int CMyClass::d;
7. Чи можна ініціалізувати статичний член класу при його оголошенні в native-класі?
Так, можна. Ініціалізація статичного члена даних класу здійснюється при його оголошенні. Наприклад:
int CMyClass::d = 10; // ініціалізація статичного члена даних
8. Як оголосити статичний член даних в managed-класі? Приклад оголошення та використання
На відміну від native-класів, у managed-класах оголошення статичного члена даних здійснюється як автоматичного (без додаткового визначення члену даних). Обов’язково потрібно задати ключове слово static.
Так само, як і в native-класах, у managed-класах екземпляри (об’єкти) класу мають доступ до однієї (тільки до однієї) ділянки фіксованої пам’яті.
Приклад. Нехай дано клас CMyRefClass, який оголошено як managed (керований, з ключовим словом ref). Такі класи використовуються в середовищі CLR.
// оголошення managed-класу ref class CMyRefClass { private: static int rd; // оголошення статичного члена в класі - тільки один раз public: CMyRefClass(void); // конструктор за замовчуванням // методи класу int Get(void) { return rd; } void Set(int nrd) { rd = nrd; } }; // визначення статичного члена - не потрібно! //int CMyRefClass::rd; // конструктор класу CMyRefClass::CMyRefClass(void) { rd = 0; }
Як видно з вищенаведеного коду, для managed-класу не потрібно окремо визначати статичний член.
Використання даного класу з іншого методу (програмного коду):
// статичні члени даних у managed-класах CMyRefClass RC1; CMyRefClass RC2; CMyRefClass ^RC3 = gcnew CMyRefClass(); // managed-покажчик на клас RC2.Set(5); int t; t = RC1.Get(); // t = 5 RC3->Set(15); t = RC2.Get(); // t = 15 RC1.Set(-20); t = RC3->Get(); // t = -20
Як видно з вищенаведеного коду, статичні члени даних у всіх класах є спільними для екземплярів цих класів, навіть якщо для екземпляру класу виділена пам’ять з допомогою оператора gcnew.
9. Які є способи доступу до загальнодоступних (public) статичних членів даних?
Якщо статичний член даних оголошений у розділі public, то доступ до нього можна отримати одним з трьох способів:
- з допомогою символу ‘ . ‘ (крапка), якщо оголошено об’єкт (екземпляру) класу;
- з допомогою послідовності символів ‘->’, якщо оголошено покажчик на об’єкт класу;
- з допомогою імені класу та символів ‘::’ (розширення області видимості). Цей спосіб працює також і для статичних членів даних, оголошених в розділах private та protected.
10. Приклад використання загальнодоступного статичного члена для native-класу
Нехай задано native-клас CMyClass, в якому оголошено загальнодоступний статичний член. У програмному коді нижче продемонстровано способи доступу до загальнодоступного статичного члена класу.
// native-клас class CMyPublicClass { public: CMyPublicClass(void); ~CMyPublicClass(void); static int d; // загальнодоступний статичний член класу // методи класу int Get() { return d; } void Set(int nd) { d = nd; } }; // визначення статичного члена класу int CMyPublicClass::d; // конструктор CMyPublicClass::CMyPublicClass(void) { d = 0; } // деструктор CMyPublicClass::~CMyPublicClass(void) { }
Демонстрація доступу до статичного члена класу з іншого програмного коду
// демонстрація доступу до загальнодоступного статичного члена класу CMyPublicClass PC1; CMyPublicClass * PC2 = new CMyPublicClass(); // покажчик на клас int t; // доступ з допомогою символу '.' PC1.d = 30; t = PC1.Get(); // t = 30 // доступ з допомогою покажчика PC2->d = 50; t = PC2->Get(); // t = 50 t = PC1.Get(); // t = 50 // доступ з допомогою оператора розширення області видимості :: CMyPublicClass::d = -33; t = PC2->d; // t = -33 t = PC1.d; // t = -33
11. Приклад використання загальнодоступного статичного члена для managed-класу
Для managed-класу доступ до статичного члена класу такий самий як і для native-класу. Нехай задано оголошення managed-класу CMyPublicClass.
// managed-клас (з ідентифікатором ref) ref class CMyPublicClass { public: CMyPublicClass(void); ~CMyPublicClass(void); static int d; // загальнодоступний статичний член класу // методи класу int Get() { return d; } void Set(int nd) { d = nd; } }; // конструктор CMyPublicClass::CMyPublicClass(void) { d = 0; } // деструктор CMyPublicClass::~CMyPublicClass(void) { }
Демонстрація різних видів доступу
// демонстрація доступу до загальнодоступного статичного члена класу CMyPublicClass PC1; CMyPublicClass ^ PC2 = gcnew CMyPublicClass(); // managed-покажчик на клас int t; // доступ з допомогою символу '.' PC1.d = 30; t = PC1.Get(); // t = 30 // доступ з допомогою покажчика PC2->d = 50; t = PC2->Get(); // t = 50 t = PC1.Get(); // t = 50 // доступ з допомогою оператора розширення області видимості :: CMyPublicClass::d = -33; t = PC2->d; // t = -33 t = PC1.d; // t = -33
12. Для чого потрібні статичні члени даних? Переваги використання статичних членів даних
Статичні члени даних класу можуть використовуватись для зв’язування об’єктів класу між собою. Вони є тією спільною ділянкою пам’яті, яку можуть використовувати різні об’єкти класу, що оголошені в різних методах. Пам’ять для статичного члену класу завжди виділена, навіть, якщо в деякому методі не оголошено жодного об’єкту.
Наприклад, можна оголосити клас, що містить статичний член даних, який підраховує кількість активних об’єктів класу. У цьому випадку реалізуються методи, що збільшують (зменшують) значення цього статичного члена. Ці методи можуть викликатись з різних частин програмного коду (методів інших класів тощо). Однак, пам’ять, що виділена для цього статичного члена даних буде спільною для усіх цих методів.
13. Які є способи доступу до прихованих статичних членів класу (оголошених в розділі private)?
Якщо статичний член класу оголошений в розділі private, то доступ до нього можна отримати одним з трьох способів:
- з допомогою оператора розширення області видимості ‘::’;
- з допомогою функції-члена класу (методу класу);
- з допомогою класу, що оголошений дружнім до даного класу.
Якщо для доступу до прихованого статичного члена даних використати оператор ‘ . ‘ або доступ за покажчиком ‘->‘, то компілятор видасть помилку.
Зв’язані теми
- C++. Поняття класу. Оголошення класу. Об’єк класу. Класи в середовищі CLR. Інкапсуляція даних в класі
- Класи пам’яті, що можуть оголошуватись при роботі з класами та об’єктами класів. Ключові слова register, extern, static, mutable
- C++. Managed та unmanaged класи у Visual C++. Огляд відмінностей роботи. Приклад реалізації managed та unmanaged класів
- Об’єкти класу як члени даних класу. Приклади