При объявлении полей класса не допускается их инициализация, поскольку в момент описания поля память для его размещения еще не выделена. Выделение памяти осуществляется не для класса, а для объектов этого класса. Поэтому возможность инициализации полей появляется после объявления данного класса.
Значение может заноситься в поле объекта во время выполнения программы несколькими способами:
· присваиванием значения полю объекта
· внутри любой компонентной функции используемого класса
· согласно общим правилам 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);
Поля перечисляются через запятую. Для каждого поля в скобках указывается инициализирующее значение, которое может быть выражением.
|
|