Слайд 2
Слід зауважити, що в класі присутня лише декларація
статичного члену, для його створення необхідно виділити пам’ять під
нього та в разі необхідності проініціалізувати – це відбувається поза межами класу, навіть якщо статичний член задекларований як закритий.
Більше того, якщо статичний член класу (скалярного типу) помічений службовим словом const, то він може бути проініціалізований в класі, але пам’ять під нього все рівно має бути виділена поза класом!
Операція sizeof не враховує пам'ять, виділену під статичні поля.
Слайд 3
Приклад.
class Example
{
public
:
static int num; // декларація статичного члену
класу
int key;
Example (int key_) : key (key_) {}
};
///////////////////////////////////////////////////////////////
int Example :: num; // виділення пам’яті під статичний член
// в разі відсутності ініціалізації він = 0
//////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
Example e (1), f (10);
cout << Example :: num << endl; // звертання через ім’я класу
Example :: num = 100;
cout << e.num << endl; // звертання через ім’я екземпляру
cout << f.num << endl; // звертання через ім’я екземпляру
e.num = 1000;
cout << e.num << endl;
cout << f.num << endl;
system("PAUSE");
return 0;
}
Слайд 4
Статичні функції-члени класів використовуються тільки для звертання до
статичних даних-членів і не можуть використовувати звичайні дані та
методи класу, адже вони не прив'язані до екземпляру, їм не передається вказівник this.
Службове слово static вказується лише у декларації статичної функції, при її визначенні воно не повторюється.
Звертання до статичних методів так само може відбуватись і через ім'я класу, і через ідентифікатор екземпляру.
Слід зауважити, що звичайні функції-члени класу мають право працювати із статичними членами класу.
Конструктор та деструктор в С++ не можуть бути статичними!
Слайд 5
Спадкування, похідні класи.
Спадкування – це один з основних
принципів об'єктно-орієнтованого програмування, який дозволяє створювати об'єкти, що спадкують
свої властивості від існуючих об'єктів, додаючи власної функціональності.
Похідний та базовий клас пов’язані співвідношенням «Є» («is-a») : якщо SubBase – похідний клас від класу Base, то SubBase «є» Base. Синтаксис визначення похідного класу:
class SubBase : <вид_спадкування> Base
{
// тіло похідного класу
};
Слайд 6
Деякі правила спадкування.
Похідний клас спадкує (містить) всі відкриті
(public) та захищені (protected) члени базового класу. Закриті (private)
члени базового класу недоступні у похідному.
Конструктори та деструктор не спадкуються похідним класом.
При створенні екземпляру похідного класу автоматично викликається конструктор базового класу і лише потім конструктор похідного. При знищенні екземпляру деструктори викликаються у зворотному порядку.
Якщо у похідному класі відсутній безпосередній виклик конструктора базового класу, то викликається конструктор за умовчанням (без параметрів) базового класу. В разі його відсутності виникає помилка.
Не спадкується також операція присвоєння, якщо вона була перевантажена у базовому класі.
Слайд 7
Доступ до членів класу при різних видах спадкування
Види
спадкування (не використовувались в мові С#) та доступ до
членів базового класу у похідному класі зазначені у наступній таблиці:
Слайд 8
Приклад.
class Base
{
protected : // закриті
члени класу
double money;
int key;
public : // відкриті члени класу
Base (double money_ = 1000, int key_ = 1):
money (money_), key (key_)
{cout << “Create Base” << endl;}
double show_money () {return money;}
int show_key () {return key;}
};
class SubBase : public Base
{
public :
// Тут автоматично викликається конструктор базового класу
SubBase (double money_, int key_)
{
cout << “Create SubBase” << endl;
money = money_; key = key_;
}
};
Слайд 9
Виклик конструктора базового класу.
class Base
{
protected :
// закриті члени класу
double money;
int key;
public : // відкриті члени класу
Base (double money_ = 1000, int key_ = 1):
money (money_), key (key_)
{ }
double show_money () {return money;}
int show_key () {return key;}
};
class SubBase : public Base
{
public :
// Тут явно викликається конструктор базового класу
SubBase (double money_, int key_): Base(money_, key_)
{ }
};
Слайд 10
Зміна доступу до членів базового класу у похідному
класі.
Оголошення доступу у похідних класах дають можливість:
зробити знову відкритими
або захищеними відповідно захищені або відкриті члени базового класу у похідному класі;
зробити знову відкритими відкриті члени базового класу у закритому або захищеному похідному класі;
Слайд 11
Приклад.
class Base
{
private :
// закриті члени базового класу
double money;
protected
: // захищені члени базового класу
int key;
public:
char symb;
};
class SubBase : public Base
{
public :
Base :: key; // захищений член базового класу –
// тепер відкритий у похідному
Base :: money; // Помилка! В похідному класі немає
// доступу до закритого члена базового класу
protected :
Base :: symb; // у похідному класі він захищений
};
Слайд 12
Зауваження про ініціалізацію екземплярів класу.
При створенні масиву екземплярів
класу виникає необхідність у конструкторі за замовчуванням (без параметрів):
class
Student
{
private :
// закриті члени класу
public :
Student (double ball_, double exam_,
char * name_ = "NoName");
// конструктор за замовчуванням
Student (char * name_ = "NoName");
~Student ();
};
int main ()
{
Student grup_1 [25]; // виклик констр. за замовч.
return 0;
}
Слайд 13
А якщо необхідний масив з проініціалізованими полями екземплярів?
В такому разі можливо передавати конструкторам аргументи наступним чином:
int
main ()
{
Student bad [] = {
Student (30,25, “Ivan"), // явний виклик
Student (32,27, “Oleg"),// явний виклик
Student (25,30, "Maria") // явний виклик
};
return 0;
}
Тут створений масив із трьох елементів, кожний з яких ініціалізується завдяки явному виклику конструктора з параметрами.
Слайд 14
Список ініціалізації.
В багатьох випадках, особливо, коли членом класу
є екземпляр деякого іншого класу, зручно ініціалізувати члени класу
так званим списком ініціалізації конструктора. Він вказується прямо після сигнатури конструктора (тобто після круглої дужки, що закриває його список параметрів) і відокремлюється від неї двокрапкою. В списку вказується ідентифікатор члену класу, а в дужках – початкове значення для нього. Елементи списку відокремлюються комами:
class Special_Student
{
Student s;
int key;
public :
Special_Student (Student s_, k) :
s (s_), key (k) // Це список ініціалізації
{ // тіло конструктора порожнє!
}
};
int main ()
{
Student s;
Special_Student c (s);
return 0;
}