- •1 Парадигми та мови програмування
- •1.1 Процедурне програмування
- •1.2 Об'єктне (модульне) програмування
- •1.3 Об'єктно-орієнтовне програмування
- •2 Програмне середовище
- •3 Базові поняття програмування
- •4 Процедурно-орієнтоване програмування
- •4.1 Функції
- •4.2 Вбудовані (inline) функції
- •4.3 Передача параметрів
- •4.4 Обчислення значення функцій
- •4.4. Обчислення значення функції — вихід із функції; особливості повернення та використання іменованого значення, іменованої константи
- •4.5 Рекурсія
- •4.5. Рекурсія
- •4.6 Довизначення (overloading) функцій
- •4.6. Довизначення (overloading) функцій
- •4.7 Узагальнені функції (function template)
- •4.8 Непряме використання функцій: указники на функції, їх тип, ініціалізація і присвоєння
- •4.9 Видимість
- •4.10 Тривалість життя об’єктів
- •5 Об'єктне програмування
- •5.1 Класи і об'єкти, члени класів
- •5.2 Інтерфейс класу, реалізація класу; визначення і оголошення класу
- •5.3 Створення і ініціалізація об'єктів, довизначення конструкторів, замовчуваний конструктор, копіювання, поверхневе і глибоке копіювання, ініціалізація і присвоєння, копіювальний конструктор
- •5.4 Cтатичні члени класів і статичні класні функції
- •5.5 Константні об'єкти, константні функції, змінювані члени константних об'єктів (mutable)
- •5.6 Поточний об'єкт this, указники на члени класу і класні функції, порівняння з указниками на (позакласні) функції, указники на статичні члени класу
5.4 Cтатичні члени класів і статичні класні функції
Cтатичні члени класів і статичні класні функції
Доповнимо клас Employee визначенням вільного ідентифікаційного коду службовця.
Самий простий спосіб — оголосити його статичною змінною:
static unsigned int currentId;
інкапсулювавши її клас, для чого її оголошення розміщується в його інтерфейсі.
Як ми пам'ятаємо, атрибути ініціалізуються особливо. Звичайні атрибути — при
створенні об'єкта. Статичний атрибут спільний для всіх об'єктів класу, а тому
ідентифікується без посилання на об'єкт і створюється компонувальником за його
визначенням, яке розміщується у файлі реалізації
unsigned int Employee :: currentId = 0;
Відповідних змін може зазнати конструктор, в якому тепер стане на параметр
менше. Залежно від обставин ним може виявитися додатково довизначений конструктор
class EmployeeP
{
friend void Payroll :: printCheck(EmployeeP *);
// також:
friend class Employer;
// крім них:
friend bool operator>
(const EmployeeP&, const EmployeeP&);
// Атрибути
private:
static unsigned int currentId;
char * name;
unsigned int id;
float salary;
// Методи
EmployeeP(char*, unsigned int, float);
EmployeeP(char*, float);
float getSalary();
public:
~EmployeeP();
void printEmployee();
char* getName();
};
Тепер займемося вдосконаленням класу Date , включивши в нього додатковий статичний
атрибут стандартної дати defaultDate .
static Date defaultDate;
З його ініціалізацією трошки складніше: статичний атрибут сам є об'єктом типу
Date . Для його ініціалізації доведеться застосувати конструктор (правильно
читайте наведений нижче текст: об'єкт defaultDate з області видимості (класу)
Date має тип Date і замовчувані значення параметрів конструктора)
<
p>Date Date :: defaultDate;
або, взявши за стандартну дату початку відрахування часу системним годинником
Date Date :: defaultDate (1, 1, 1970);
Маємо на увазі, що два написаних вище рядки є альтернативними визначеннями
об'єкту, а тому в програмі може бути присутнім лише одне з них. При необхідності
зміни стандарної дати слід визначити функцію її встановлення
void Date::setDefault (int d, int m, int y)
{
defaultDate = Date(d, m, y);
}
за значеннями параметрів або за системним годинником
void Date :: setDefault ()
{
struct tm * today =new tm;
time_t timer;
time( &timer );
today = gmtime(&timer);
defaultDate._day = today->tm_mday;
defaultDate._month = ++(today->tm_mon);
defaultDate._year = today->tm_year+=1900;
}
Функція одержує setDefault особливий статус. Вона не потребує для свого виклику
жодного об'єкту, оскільки працює не з атрибутами певного об'єкту, а статичним
атрибутом класу. Ось як зміниться інтерфейс
class Date
{
static Date defaultDate;
int _day, _month, _year;
public:
Date (int d, int m, int y);
Date (int d, int m);
Date (int d);
Date ();
Date (const char *cdate);
Date (const Date&);
void showDate();
static void setDefault(int,int,int);
static void setDefault();
static void showDefault();
}
Попутно ми визначимо також функцію виводу стандартної дати. Вона теж статична
void Date::showDefault()
{
cout<<defaultDate._day<<':'
<<defaultDate._month<<':'
<<defaultDate._year<<endl;
}
Наявність стандартної дати дозволяє визначити конструктор більш елегантно
Date::Date ( int d, int m, int y)
{
_day = d? d: defaultDate._day;
_month=m? m: defaultDate._month;
_year= y? y: defaultDate._year;
};
перенісши інші варіанти виклику конструктора в замовчування
class Date
{
static Date defaultDate;
int _day, _month, _year;
public:
Date (int d=0, int m=0, int y=0);
Date (const char *cdate);
Date (const Date&);
void showDate();
static void setDefault(int,int,int);
static void setDefault();
static void showDefault();
}
Ось як може використовуватися клас Date
int main()
{
Date::showDefault();
Date::setDefault();
Date::showDefault();
Date::setDefault(11, Date::feb, 2003);
Date::showDefault();
Date copyDefault = Date();
copyDefault.showDate();
return 0;
}
Звернемо увагу на те, що Date() і Date::defaultDate стали тепер синонімами,
але з різними областями видимості і правами доступу.