- •Часть 3. Объектно-ориентированное программирование
- •Екатеринбург
- •Введение
- •Классы Описание класса
- •Описание объектов
- •Указатель this
- •Конструкторы
- •Конструктор копирования
- •Конструктор копирования для класса monstr:
- •Статические элементы класса
- •Статические поля
- •Статические методы
- •Дружественные функции и классы Дружественные функции
- •Дружественный класс
- •Деструкторы
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Наследование Ключи доступа
- •Простое наследование
- •Правила наследования методов
- •Виртуальные методы и механизм позднего связывания
- •Абстрактные классы
- •Обработка исключительных ситуаций
- •Синтаксис исключений
- •Перехват исключений
- •Список исключений
- •Иерархии исключений
- •Библиографический список
- •Оглавление
- •Часть 3. Объектно-ориентированное программирование
- •620002, Екатеринбург, ул.Мира, 19
- •620002, Екатеринбург, ул.Мира, 19
Указатель this
Каждый объект содержит свой экземпляр полей класса. Методы класса находятся в памяти в единственном экземпляре и используются всеми объектами совместно, поэтому необходимо обеспечить работу методов с полями именно того объекта, для которого они вызваны. Это обеспечивается передачей в функцию скрытого параметра this, в котором хранится константный указатель на вызвавший функцию объект.
Указатель this неявно используется внутри метода для ссылок на элементы объекта. В явном виде этот указатель применяется в основном для возвращения из метода указателя (return this;) или ссылки (return *this;) на вызвавший объект.
Добавим в класс monstr новый метод, возвращающий ссылку на наиболее сильного (поле health) из двух монстров, один из которых вызывает метод, а другой передается ему в качестве параметра (метод следует поместить в секцию public описания класса):
Monstr & the_best (monstr &M) {
If (health >M.get_health ( )) return *this;
Return M;
}
…
monstr Vasia (50), Super (200);
monstr Best = Vasia.the_best (Super); // новый объект
// Best инициализируется значениями полей Super
Указатель this можно применять также для идентификации поля класса в том случае, когда его имя совпадает с именем формального параметра. Другой способ – использовать операцию доступа к области видимости (::):
void cure (int health, int ammo) {
this -> health +=health; // используется this
monstr :: ammo +=ammo; // использование ::
}
Конструкторы
Конструктор предназначен для инициализации объекта и вызывается автоматически при его создании. Его свойства:
- конструктор не возвращает значение даже типа void. Нельзя получить указатель на конструктор;
- класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации (при этом используется механизм перегрузки);
- конструктор, вызываемый без параметров, называется конструктором по умолчанию;
- параметры конструктора могут иметь любой тип, кроме типа этого же класса. Можно задавать значения параметров по умолчанию. Их содержит только один из конструкторов;
- если программист не указал ни одного конструктора, компилятор создаст его автоматически;
- конструкторы не наследуются;
- конструкторы нельзя описывать с модификаторами const, virtual и static;
конструкторы глобальных объектов создаются, как только становится активной их область действия;
- конструктор вызывается, если в программе встретилась какая-либо из следующих синтаксических конструкций:
имя_класса имя_объекта [(список параметров)];
// список параметров не должен быть пустым
имя_класса (список параметров);
// создается объект без имени
имя_класса имя_объекта = выражение;
// создается объект без имени и копируется
Примеры
monstr Super (200, 300), Vasia (50), Z;
monstr X = monstr (1000);
monstr Y = 500;
В первом операторе создаются три объекта.
Во втором операторе создается безымянный объект со значением параметра health = 1000; выделяется память под объект X, в которую копируется безымянный объект.
В третьем операторе создается безымянный объект со значением параметра health= 500; выделяется память под объект Y, в которую копируется безымянный объект. Такая форма создания объекта возможна в том случае, если для инициализации объекта допускается задать один параметр.
Пример. Усовершенствованный класс monstr с несколькими конструкторами:
Enum color {red, green, blue}; //
class monstr {
int health, ammo;
color skin; //
char *name; //
public
monstr (int he =100, int am = 10);
monstr (color, sk);
monstr (char *nam);
int get_health ( ) {return health;}
int get_ammo ( ) {return ammo;}
…
};
//---------------------------------------------
monstr : : monstr (int he, int am) {
health = he; ammo = am; skin = red; name = 0;
}
//----------------------------------------------
monstr : : monstr (color sk) {
switch (sk) {
case red : health = 100; ammo = 10; skin = red; name = 0;
break;
case green : health = 100; ammo = 20; skin = red; name = 0;
break;
case blue : health = 100; ammo = 40; skin = red; name = 0;
break;
}
}
//------------------------------------------------
monstr : : monstr (char *nam) {
name = new char [strlen(nam)+1];
strcpy (name, nam);
health = 100; ammo = 10; skin = red;
}
…
//-------------------------------------------------
monstr *m = new monstr (“Ork”);
monstr Green (green);
Первый из приведенных выше конструкторов является конструктором по умолчанию, поскольку его можно вызвать без параметров. Объекты класса monstr теперь можно инициализировать разными способами, требуемый конструктор будет вызван в зависимости от списка значений в скобках. При задании нескольких конструкторов следует соблюдать те же правила, что и при перегрузке функций.
!!! Перегружать можно не только конструкторы, но и другие методы класса.
Еще один способ инициализации полей в конструкторе – с помощью списка инициализаторов, расположенных после двоеточия между заголовком и телом конструктора:
Monstr : : monstr (int he, int am) :
health (he), ammo (am), skin (sk), name (0) {};
Поля перечисляются через запятую. Для каждого поля в скобках указывается инициализирующее значение, которое может быть выражением. Таким образом инициализируются поля-константы, поля-ссылки и поля-объекты. В последнем случае будет вызван конструктор, соответствующий указанным в скобках параметрам.
Задание
Добавьте в разработанный вами класс-калькулятор конструктор, инициализирующий объект.