class class_name
/**
int data_member; // поля
void show_member(int); // методы
**/;
Пример:
class employee
/** char name[64] ;
long employee_id;
float salary;
void show_employee(void)
/** cout << "Имя: " << name << endl;
cout << "Номер служащего: " << employee_id << endl;
cout << "Оклад: " << salary << endl;
**/;
**/;
class имя
/** private:
…
protected:
…
public:
…
**/;
Атрибут private имеют поля и методы класса, доступные только для составных и дружественных функций этого класса. Эти поля и методы класса называются закрытыми.
Атрибут protected имеют поля и методы класса, доступные для составных и дружественных функций классов, которые являются производными от этого класса или совпадают с ним. Эти поля и методы класса называются защищенными.
Атрибут public имеют поля и методы класса, обращение к которым осуществляется как к полям структуры. Эти поля и методы называются открытыми.
Вместо слова class в объявлении класса как нового типа данных допустимо использовать слова:
Struct class_name
/**
int data_member; // поля
void show_member(int); // методы
**/;
или
Union class_name
/**
int data_member; // поля
void show_member(int); // методы
**/
Если первичный класс объявлен с ключевым словом class, то первые его члены будут закрытыми по умолчанию, если как struct, то открытыми. В случае union члены класса могут быть только открытыми.
Например:
class Vector
/** double x,y;
public:
double getx() /**return x;**/
double gety() /**return y;**/
**/
то элементы класса x и y будут закрыты по умолчанию, и обращение к ним, как к открытым членам, приведет к ошибке. Эти элементы можно будет читать с помощью функции getx() и gety()
Произвольная внешняя функция, прототип которой объявлен в теле класса и имеет модификатор friend, называется дружественной функцией этого класса.
Функция, не являющаяся членом класса, может иметь доступ к его частным членам в случае, если она объявлена другом (friend) класса. Например, в следующем примере функция frd() объявлена другом класса cl (при этом реализована она может быть где угодно):
class cl /**
...
public:
friend void frd();
...
**/;
Одна из причин, почему язык С++ допускает существование функций-друзей, связана с той ситуацией, когда два класса должны использовать одну и ту же функцию.
class employee
/** public:
char name[64];
long employee_id;
float salary;
void show_employee(void); |————————> Прототип функции
**/;
Так как разные классы могут использовать функции с одинаковыми именами, нужно предварять имена определяемых вне класса функций именем класса и оператором глобального разрешения (::). В данном случае определение функции становится следующим:
void employee:: show_employee (void)
/** сout << "Имя: " << name << endl;
cout << "Номер служащего: " << employee_id << endl;
cout << "Оклад: " << salary << endl;
**/;
Для заполнения полей объекта при его создании и для освобождения полей при его удалении в Си++ предусмотрено специальное средство, которое состоит из составных функций, называемых конструктором и деструктором.
Класс может иметь несколько конструкторов. Имя каждого конструктора совпадает с именем класса, для которого этот конструктор определен. Конструкторы могут быть перегружены и иметь параметры по умолчанию.
Конструктор не имеет возвращаемого значения.
Конструктор может быть объявлен и в закрытой, и в защищенной, и в открытой части класса. Если конструктор объявлен в закрытой части, то объекты этого класса могут создаваться только дружественными функциями, а если в защищенной – дружественными функциями производного класса.
Конструктор может быть определен вне тела класса.
Определим класс двумерного вектора. Будем инициализировать его с помощью полярных координат:
#include <iostream.h>
#include <math.h>
class Vector
/** double x, y;
public:
Vector( double rho, double phi);
void show() /** cout << "Вектор = ("<< x << ", " << y << ")\n"; **/
**/;
Vector::Vector(double rho, double phi = 0)
/**
x = rho*cos(phi);
y = rho*sin(phi);
**/
void main()
/**
Vector v(1), w(-1, 0.5);
v.show(); w.show();
getch();
**/
Результаты работы программы
Вектор = (1, 0)
Вектор = (-0.877583, -0.479426)
Обращение к конструктору осуществляется одним из трех способов:
имя объект(параметры);
имя объект = имя(параметры);
имя объект = параметр;
где имя обозначает имя класса. Второй способ называется явным, третий – сокращенным.
Конструктор имеет дополнительное средство для инициализации полей. Это средство называется списком инициализации.
Список инициализации находится в заголовке определения конструктора и отделяется от прототипа конструктора двоеточием. Он состоит из слов поле(выражение), инициирующих арифметические выражения над аргументами.
class Arr // массив чисел с плавающей точкой
/** int n; // максимальное число элементов
double *p; // указатель на массив
public:
Arr(int size, double *a): n(size), p(a) /****/
**/
В данном примере список инициализации означает то же самое, что и присваивания n = size и p = a.
Преимущество списка инициализации заключается в том, что он позволяет задавать начальные значения констант и псевдонимов (ссылок).
Деструктором называется составная функция класса, которая вызывается перед разрушением объекта. Это означает, что деструктор вызывается в следующих случаях:
при выходе из области видимости;
при выполнении операции delete для объектов, размещенных в динамической памяти;
непосредственно, как составная функция.
Правила определения деструкторов:
класс имеет ровно один деструктор;
имя деструктора совпадает с именем класса с добавленным впереди символом тильды «~»;
деструктор не имеет аргументов и не имеет возвращаемого значения.
Если же деструктор не определить явно, то он будет определен по умолчанию, как составная функция
~ имя_класса() /****/;
и будет находиться в открытой части класса.