Партнерка на США и Канаду по недвижимости, выплаты в крипто
- 30% recurring commission
- Выплаты в USDT
- Вывод каждую неделю
- Комиссия до 5 лет за каждого referral
Операцию [] можно определять только как метод класса.
Перегруженные операции – функции-члены против дружественных функций.
Если перегруженная операция реализована как функция-член, то ей либо вообще не передаются явно параметры, либо передается один параметр. Дружественной функции - перегруженной операции - передается один, либо два параметра.
Если бинарная операция перегружена как функция-член, то ее первым операндом является объект, который принимает сообщение. Явно передается только один параметр.
Если унарная перегруженная операция реализована как функция-член, то ее операндом является принимающий сообщение объект. Эта функция-член не имеет явных параметров. Перегруженная операция не может иметь более двух параметров.
Фунция-член Class X { X operator-() const; // Унарный минус X operator&() const; // Вычисление адреса X operator^() const; // Ошибка: операция ^ - бинарная }; | Дружественная функция class Y { friend Y operator-(const Y&); friend Y operator&(const Y&); freind Y operator^(const Y&); }; |
Class X { X operator-(const X&) const; // бинрный минус X operator&( const X&) const; // побитовое И }; | class Y { friend Y operator-(const Y&,const Y&); friend Y operator&(const Y&, const Y&); }; |
5. Наследование
5.1. Основные понятия
Наследование - механизм создания нового класса из старого. К существующему классу можно что-либо добавить, или изменять его каким-либо образом для создания нового (порожденного) класса. Это мощный механизм для повторного использования кода. Наследование позволяет создавать иерархию связанных типов, совместно использующих код и интерфейс. Большинство полезных типов представляют собой различные варианты друг друга, утомительно выписывать для каждого один и тот же код. Порожденный класс наследует описание основного класса. Затем он может изменяться с добавлением членов, изменения функций существующих членов и изменения привилегий доступа.
Механизм наследования классов позволяет строить иерархии, в которых производные классы получают элементы родительских, или базовых, классов и могут дополнять их или изменять их свойства. При большом количестве никак не связанных классов управлять ими становится невозможным. Наследование позволяет справиться с этой проблемой путем упорядочивания и ранжирования классов, то есть объединения общих для нескольких классов свойств в одном классе и использования его в качестве базового. Классы, находящиеся ближе к началу иерархии, объединяют в себе наиболее общие черты для всех нижележащих классов. По мере продвижения вниз по иерархии классы приобретают все больше конкретных черт.
Порожденный (производный) класс. Для порождения нового класса от существующего может использоваться следующая форма записи:
class имя класса : (public | protected | private) имя базового класса {
объявления членов };
Одна из особенностей порожденного класса - видимость унаследованных членов. Для определения доступности членов основного класса порожденному классу используются ключевые слова public, protected и private.
5.2. Режимы доступа к членам базового класса
При описании класса в его заголовке перечисляются все классы, являющиеся для него базовыми. Возможность обращения к элементам этих классов регулируетсяс помощью ключей доступа private, protected и public:
class имя : [private | protected | public] базовый_класс
{ тело класса };
Если базовых классов несколько, они перечисляются через запятую. Ключ доступа может стоять перед каждым классом, например:
class А { ... };
class В { ... };
class С { ... };
class D: А. protected В. public С { ... }:
По умолчанию для классов используется ключ доступа private, а для структур —public.
Ключ доступа | Спецификатор в базовом классе | Доступ в производном классе |
private | private protected public | нет private private |
protected | private protected public | нет protected protected |
public | private protected public | нет protected public |
Элементы private базового класса в производном классе недоступны вне зависимости от ключа. Обращение к ним может осуществляться только через методы базового класса. Элементы protected при наследовании с ключом private становятся в производном классе private, в остальных случаях права доступа к ним не изменяются. Доступ к элементам public при наследовании становится соответствующим ключу доступа. Если базовый класс наследуется с ключом private, можно выборочно сделать некоторые его элементы доступными в производном классе, объявив их в секции public производного класса с помощью операции доступа к области видимости:
class Base{
public: void f();
class Derived : private Base{
public: Base: :vo1d f O :
5.3. Простое наследование
Простым называется наследование, при котором производный класс имеет одного родителя. Для различных методов класса существуют разные правила наследования — например, конструкторы и операция присваивания в производном классе не наследуются, а деструкторы наследуются.
Пример 5.1. Создадим производный от класса monstr класс daemon, добавив способность думать.
enum color {red. green, blue};
/ / Класс monstr
class monstr{
/ / Скрытые поля класса:
1nt health, ammo;
color skin;
char *name;
public:
/ / Конструкторы:
monstr(int he = 100. int am = 10);
monstr(color sk);
monstr(char * name);
monstr(monstr &M);
/ / Деструктор:
~monstr(){delete [ ] name;}
/ / Операции:
monstr& operator ++(){
++health; return *this;}
monstr operator ++(int){
monstr M(*this); health++: return M;
}
operator int(){
return health;
}
bool operator >(monstr &M){
1f( health > M. health) return true;
return false;
}
const monstr& operator = (monstr &M){
if (&M == this) return *this;
If (name) delete [] name;
If (M. name){
name = new char [strlen(M. name) + 1];
strcpy(name. M. name);}
else name = 0 ;
health = M. health; ammo = M. ammo; skin= M. skin;
return *this;
}
// Методы доступа к полям:
int get_health() const {return health;}
int get__ammo() const {return ammo;}
// Методы, изменяющие значения полей:
void change_health(int he){ health = he;}
// Прочие методы:
void draw(int x, int y, int scale, int position):
}:
// -- Реализация класса monstr
monstr::monstr(int he, int am):
health (he), ammo (am), skin (red), name (0){}
monstr::monstr(monstr &M){
if (M. name){
name = new char [strlen(M. name) + 1];
strcpy(name. M. name);}
else name = 0;
health - M. health; ammo - M. ammo; skin = M. skin;
}
monstr::monstr(color sk){
switch (sk){
case red: health - 100; ammo=10; skin = red; name = 0; break;
case green: health = 100: ammo=10; skin = green; name = 0; break;
case blue:health = 100;ammo= 40;skin = blue; name = 0; break;
} }
monstr::monstr(char * nam){
name = new char [strlen(nam) + 1];
strcpy(name, nam);
health = 100; ammo = 10: skin = red; }
void monstr::draw(int x, int y. int scale, int position)
/* Отрисовка monstr */
// Класс daemon —
class daemon : public monstr{
int brain;
public:
// Конструкторы:
daemon(int br = 10){brain = br;};
daemon(color sk) : monstr (sk) {brain = 10;}
daemon(char * nam) : monstr (nam) {brain = 10:}
daemon(daemon &M) : monstr (M) {brain = M. brain;}
// Операции:
const daemon& operator = (daemon &M){
i f (&M == this) return *this;
brain = M. brain;
monstr::operator « (M);
return *this;
}
// Методы, изменяющие значения полей:
void think():
// Прочие методы:
void drawCint х. int у. int scale, int position):
}:
// Реализация класса daemon
void daemon : :think(){ /* ... */ }
void daemon::draw(int x, int y, int scale, int position)
{ /* ... Отрисовка daemon */ }
В классе daemon введено поле brain и метод think, определены собственные конструкторы и операция присваивания, а также переопределен метод отрисовки draw. Все поля класса monstr, операции (кроме присваивания) и методы get_health, get_ammo и change_health наследуются в классе daemon, а деструктор формируется по умолчанию.
5.4. Конструкторы и деструкторы производных классов
Правила наследования конструкторов.
Конструкторы не наследуются, поэтому производный класс должен иметь собственные конструкторы. Порядок вызова конструкторов определяется правилами.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |


