-
Notifications
You must be signed in to change notification settings - Fork 0
CPP 03. Классы и объекты в CPP. Определение класса с помощью class, struct, union. Ограничение доступа к членам класса в CPP. Члены класса и объекта. Методы класса и объекта. Константные члены класса. Схемы наследования.
Класс – тип данных, представляющий совокупность атрибутов объекта (переменные члены класса) и возможных операций над этими объектами (методов класса). Описывается в заголовочных файлах.
Механизм описания класса:
struct
class
-
union
– не может быть базовым классом, и не может быть производным (поэтому нет уровня доступаprotected
). Нужен только для совместимости с Си. Его использование нежелательно, т.к. нет контроля со стороны компилятора.
У struct по умолчанию уровень доступа для членов public, а у class – private. У union – public. В union нет уровня protected, так как union не может быть ни базовым классом, ни производным.
По умолчанию в структуре и объединении члены классов открыты, в классе закрыты, чем достигается принцип инкапсуляции (нет доступа к данным извне)
Другое отличие структуры от класса: схема наследования по умолчанию у класса private
, а у структуры - public
.
class <имя класса> [ : <список базовых классов>] {
private: //доступ к данным есть только внутри самого класса
int a;
protected: //доступ есть внутри класса и во всех его наследниках
int b;
public: //доступны для внешнего кода
int f();
}; //класс заканчивается ; как и структура
//В библиотечных классах лучше располагать члены в обратном порядке (начиная с public)
//Классы описываются в заголовочных файлах .h. Методы же определяются в .cpp
3 схемы наследования:
-
private
(схема по умолчанию): все члены базового класса получают уровень доступаprivate
, причём из унаследованного класса нет доступа кprivate
полям базового класса. -
protected
: члены базового классаpublic
получают уровень доступаprotected
-
public
: все члены базового класса наследуются со своим уровнем доступа.
class A
{
private:
int a;
protected:
int b;
public:
int f();
};
class B: private A // public / protected
{
private:
int c;
protected:
int d;
public:
int g(); // все члены базового класса получат уровень доступа private
};
Для того, чтобы восстановить уровень доступа можно написать:
public:
using A::f;
Вариант с private
: произошла полная подмена интерфейса (f()
-> g()
)
Вариант с protected
: интерфейс тоже полностью подменяется, но у производных классов есть доступ к полям базового класса (b
и f()
перешли в уровень protected
, все остальное без изменений).
Вариант с public
: все члены со своим доступом, произошло расширение интерфейса.
Нужна возможность подмены интерфейса при наследовании (чтобы модифицировать программу, не изменяя уже написанный код), а наследование private и protected такой возможности не дают.
Модификатор final
запрещает наследование от этого класса.
Члены класса не относятся к конкретному объекту, они общие для всех объектов данного класса. Перед ними ставится ключевое слово static. Память под них не относится к объекту (при вызове sizeof они не будут учитываться).
Размещение полей класса публичными – плохой тон, поскольку это противоречит принципу инкапсуляции (скрывание реализации, предоставление пользователю только интерфейса для работы).
Поля:
- Члены объекта
- Члены класса (
static
)
Методы:
- Методы объекта
- Методы класса (
static
)
class A
private:
int a; // Член объекта
const int ca; // Константный член объекта
static int sa; // Член класса
static const int sca; // Константный член класса
public:
int f(); // Метод объекта
int f() const; // Константный метод объекта
static int sg(); // Метод класса
A(int ia) :
// Объект еще не создан
a(ia), // Так можно - объекта еще нет
ca(ia), // Так можно - объекта еще нет
sa(ia), // Ошибка - sa не член объекта
csa(ia) // Ошибка - cas не член объекта
{
// Объект создан
a = ia; // Так можно
ca = ia; // Константу изменить нельзя - объект уже создан
sa = ia; // Так можно
csa = ia; // Константу изменить нельзя - объект уже создан
}
};
// static поля класса можно проинициализировать здесь
int A::sa = 0;
const int A::csa = 0;
Константный метод объекта обязуется не изменять поля объекта.
Метод класса вызывается имя_класса::имя_метода. Метод объекта вызывается через сам объект. Методы объекта/класса имеют доступ ко всем элементам класса. Методы класса не получают this
. Методы класса могут работать только со статическими членами.
Метод класса не может быть константным, т.к. не принимает указатель на объект (this
)
int A::f() // :: - оператор доступа к контексту
// Используется для определения метода вне класса
{
return this->a; // this – ключевое слово объекта, его можно не писать
// return a; - равносильно
}
int A::sg()
{
return sa;
}