Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №4,№5.pdf
Скачиваний:
107
Добавлен:
11.02.2015
Размер:
1.13 Mб
Скачать

Основы создания программ в Си

Page 45 of 58

Конструкторы и параметры

Конструктор копирования вызывается неявным образом при передаче в функцию параметраобъекта по значению и при возврате значения из функции. При других способах передачи параметра конструктор копирования не вызывается (пример 5.4).

Пример 5.4: Конструкторы и параметры:

class Money

{

public: // конструктор инициализации без аргументов

Money(const double &r = 0.0)

{

Summa = r;

}

friend bool operator == (const Money &a, const Money &b); friend bool operator != (const Money &a, const Money &b);

private: double Summa;

};

void fl(Money t){};

// пo значению

void f2(Money *t){};

// по адресу

void f3(const Money &t){};

// пo константной ссылке

void f4(Money &t){};

// по ссылке

// код в методе main

 

Money d2(100);

// инициализация

fl(d2);

// пo значению -

 

// вызов конструктора копирования

f2(&d2);

// по адресу - конструкторы не вызываются

f3(d2);

// пo константной ссылке - нe вызываются

f4(d2);

// по ссылке - не вызываются

 

 

Конструктор копирования вызывается для создания скрытой «внутренней» копии объекта. При передаче в качестве параметра выражения может вызываться конструктор инициализации.

f1(120): // по значению - вызывается конструктор инициализации

Основы создания программ в Си

Page 46 of 58

 

 

 

f3(120): // по константной ссылке - вызываеся конструктор инициализации

Конструкторы позволяют более естественным образом задавать значения параметров по умолчанию.

void f1

(Money t = 100);

void f3

(const Money &t = 200);

void

f2

(Money *t = new Money);

void

f2

(Money *t = new Моnеу(ЗОО));

 

 

 

Вызов функций без аргумента во всех случаях сопровождается вызовом конструктора инициализации.

Константы в классе

В классе разрешается определять целочисленные константы; к целочисленным типам относятся char, short, int и long в знаковом и беззнаковом виде, bool, а также перечислимый тип enum. Константу в классе можно определить одним из двух способов:

как перечислимый тип enum;

как статическую константу целочисленного типа.

class Constant

{

public:

enum Days { mon = 1, tue, wed, thu, fri, sat, sun = 0 };

static const int

cl

= 1;

static const char

c2

= 'x';

static const Days

c3 = sun;

};

 

 

Обращение к перечислимым константам осуществляется либо по имени объекта, либо по имени класса:

cout << Constant::sat << endl; // квалификатор-класс

Constant dd;

cout << dd.sat << endl;

// квалификатор-объект

Обращение к статическим константам обычно делается по имени класса:

cout

<<

Constant::c1

<<

endl;

//

выводит

1

cout

<<

Constant::c2

<<

endl;

//

выводит

x

 

 

 

 

 

 

 

 

Основы создания программ в Си

Page 47 of 58

 

 

 

cout << Constant::c3 << endl;

// выводит 0

 

 

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

class Constants

 

{

 

const long c1;

// целочисленное константное поле

const double c2;

// нецелочисленное константное поле

public:

 

Constants(const double &r = 0)

:c2(r), c1(1) // список инициализации конструктора

{ };

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

};

 

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

1.Инициализировать в списке инициализации можно и константные поля, и обычные поляпеременные.

2.Независимо от порядка перечисления полей в списке инициализации, поля получают значения в порядке объявления в классе.

3.В качестве инициализирующего выражения можно задавать любое вычисляемое выражение (не обязательно константное), результатом которого является значение того же (или приводимого) типа, что и тип инициализируемого поля; для полей типа класс выполняется вызов конструктора.

4.Для инициализации поля встроенного типа нулем используется специальная форма инициализатора имя_поля() - выражение не задается; для поля-объекта некоторого класса вызывается конструктор без аргументов (по умолчанию).

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

6.Список инициализации выполняется до начала выполнения тела конструктора.

Основы создания программ в Си

Page 48 of 58

Поля-массивы в классе

В классе можно объявить поле-массив. Размер массива должен задаваться константным выражением, причем константные выражения должны быть определены раньше массива. Задавать количество элементов поля-массива следует обязательно (см. пример 5.5).

Пример 2.5. Поля-массивы в классе

class Arrays

{

int m0[10];

static const unsigned int k = 10; enum { n = 10 };

int m1[k]; int m2[n];

public: Arrays ()

{

for (int i = 0; i < k; ++i) m0[i]=m1[i]=m2[i]=0;

}

};

Массив инициализируется либо в теле конструктора (только неконстантный), либо в списке инициализации, причем в списке инициализации разрешается только инициализация нулем.

Arrays(): m0(), ml(), m2()

{}

Для массива объектов некоторого типа такая запись означает вызов конструктора по умолчанию (без аргументов). Конструктор вызывается для каждого элемента массива.

Операция индексирования

При наличии поля-массива в классе часто бывает необходимо перегрузить операцию индексирования [ ]. Операция перегружается только как метод класса; она является бинарной:

левый аргумент— это текущий объект,

а правый — аргумент функции-операции.

Выражение объект [индекс] трактуется как

обьект.орегаtor[ ](индекс)