Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование_С++_ч_3.doc
Скачиваний:
14
Добавлен:
22.11.2018
Размер:
217.6 Кб
Скачать

Указатель 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) {};

Поля перечисляются через запятую. Для каждого поля в скобках указывается инициализирующее значение, которое может быть выражением. Таким образом инициализируются поля-константы, поля-ссылки и поля-объекты. В последнем случае будет вызван конструктор, соответствующий указанным в скобках параметрам.

Задание

Добавьте в разработанный вами класс-калькулятор конструктор, инициализирующий объект.