Инициализация полей объектов

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

Значение может заноситься в поле объекта во время выполнения программы несколькими способами:

· присваиванием значения полю объекта

· внутри любой компонентной функции используемого класса

· согласно общим правилам C++ с использованием оператора инициализации.

Эти правила применимы только для инициализации общедоступных полей, описанных в секции public. Инициализация полей, описанных в секциях private и protected возможно только с помощью компонентной функции.

Пример 1

Пример метода, определенного в другом месте программы с помощью операции доступа к области видимости (::)

Void monstr::draw(int x, int y, int scale, int position)

{

<тело метода>

}

Пример 2

Пример описания метода, определенного как встроенный вне класса с пометкой директивы inline.

Inline int monstr::get_ammo()

{

return ammo;

}

Пример 3

Примеры доступа к элементам объекта аналогично доступу к полям структуры.

Для обращение через имя объекта

-> – через указатель

int n=Vasia.get_ammo();

stdio[5].draw(10,10,1,1);

cout<<beavis-> get_health();

В случае, когда обращаются к const объекту, к нему применяется только const методы.

Объект типа const (константный объект)- объект, значение полей которого изменять запрещено.

Пример 4

Class monstr

{…

int get_health() const {return health;}

};

const monstr Deaf(0,0); /* константный объект */

cout<<Dead.get_health();


 


Конструкторы

В C++ предназначены специальные методы для инициализации объектов - конструкторы. Они выполняются автоматически при создании объекта. Конструктор имеет то же самое имя, что и класс и обладает следующими свойствами:

· конструктор не возвращает значения, даже типа void; нельзя получить указатель на конструктор

· класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации (при этом используется перегрузка)

· конструктор может не иметь параметров, тогда это конструктор по умолчанию

· параметры конструктора могут иметь любой тип, кроме типа этого же класса; можно задавать значения по умолчанию, но их может содержать только один конструктор

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

· конструкторы не наследуются

· конструкторы нельзя записать с модификаторами: const, virtual, static

· конструкторы глобальных объектов вызываются до вызова функции main

В иерархии классов конструкторы выполняются в порядке их "классового происхождения".

Локальные объекты создаются, как только становятся активными области памяти конструктор записывается при создании временного объекта, например при передаче объекта из функции.

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

Конструктор копирования

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

T::T(const T&)

{

/* Тело конструктора */

}

Конструктор вызывается, когда новый объект создается путём копирования существующего:

· при передаче нового объекта с инициализацией другим объектом

· при передаче объекта в функцию по значению

· при возврате объекта из функции.

Конструктор копирования выполняет поэлементное копирование полей. В случае, когда в классе есть указатели или ссылки, использование конструктора копирования будет неправильным.

 

Пример 1

monst::monstr(const 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;

}

 

В конструкторах может использоваться список инициализации, который отделяется от заголовка конструктора символом «:» и состоит из записей вида: <имя>(<список выражений>), где в качестве имени может быть использовано:

имя поля данного класса

имя объекта другого класса, включенного в данный класс

имя базового класса

Список выражений определяет значения, использованные для инициализации объекта. Чаще всего конструктор со списком инициализации применяется для задания назначенных значений объекта, в котором используются фиксированные и ссылочные поля, являющиеся объектами других, ранее определенных классов.

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

Пример 2

/* Создается объект без имени и копируется */

monst Super(200, 300), Vasia(50), z;

monst x=monstr(1000);

monst y=500;

lnum color{red, green, blur} /* возможные значения цветов */

Class monstr

{

int health, ammo;

color skin;

char *name;

public:

monstr(in the = 100, int am = 10);

monstr(color 5k);

monstr(char * name);

int get_health() {return health;}

int get_ammo() {return ammo;}

};

Monstr::monst(int he, int am)

{

health = he;

ammo = am;

skin = red;

name =?;

}

Monstr::monst(color sk)

{

Switch(sk)

{

case red:

health = 100;

ammo = 10;

skin = red;

name = 0;

break;

case green:

health = 100;

ammo = 20;

skin = green;

name = 0;

break;

case blue:

health = 100;

ammo = 40;

skin = blue;

name = 0;

break;

}

}

monstr::monstr(char * name)

{

nam = new char[strlen(name) + 1];

strcpy(name, nam);

health = 100;

ammo = 10;

skin = red;

}

monstr *m = new monstr (“Ork”);

monstr Green(green);

 

Существует еще один способ инициализации полей в конструкторе - инициализация с помощью списка инициализации, расположенного после «:» между заголовком тела и конструктором.

monstr::monst(in the, int am):health(he), ammo(am), skin(red), name(0);

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: