Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по Технологии разработки ПО 2005.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
833.54 Кб
Скачать

Перегруженные конструкторы

Из программы видно, что инициализация переменной d2 класса Distance производится в момент её создания, путём вызова конструктора с аргументами:

Distance(int ft, float in): feet(ft), inches(in) // конструктор с двумя аргументами

Здесь мы инициализируем поля feet, inches теми значениями, которые передаются конструктору в качестве аргументов.

Если же для нас важно, какими значениями будут инициализироваться поля объектов класса (d1 и d3) при объявлении, то следует явно определить конструктор, что и сделано в рассматриваемой программе:

Distance(нет аргументов): feet(0), inches(0.0) { } // конструктор без аргументов

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

Итак, в программе имеется два явно определённых конструктора с одним и тем же именем Distance(). В этом случае говорят, что конструктор является перегруженным. Какой из этих двух конструкторов исполняется во время создания нового объекта, зависит от того, сколько аргументов используется при вызове. Спроси у студентов, какие конструкторы вызываются:

Distance dlina; // вызывает 1-ый конструктор

Distance shirina(11, 6.2); // вызывает 2-ой конструктор

Определение методов класса вне класса

Определять методы класса внутри самого класса не является обязательным. Как видно из программы, метод add_dist() определён вне класса Distance. Внутри определения класса содержится лишь прототип функции add_dist(). Заголовок функции содержит следующие синтаксические элементы:

void Distance::add_dist(Distance d2, Distance d3)

Аргументы функции

имя функции

Возвращаемый тип

Операция глобального разрешения

Имя класса

Такая форма записи с операцией глобального разрешения устанавливает взаимосвязь функции и класса и означает, что функция является методом класса Distance.

Теперь рассмотрим программу более детально. Объекты d1 и d3 создаются при помощи конструктора по умолчанию (конструктора без аргументов), а объект d2 – при помощи конструктора, принимающего два аргумента, значения которых инициализируют поля объекта d2. Значения для инициализации объекта d1 вводятся пользователем при помощи метода getdist().

Величины, которые мы хотим сложить, передаются в качестве аргументов методу add_dist(). Если внимательно изучить функцию add_dist(), то станет видно, что методу класса всегда предоставлен доступ к полям объекта, для которого он вызван. Можно рассматривать объект d3 как псевдоаргумент функции add_dist(), так как формально он не является аргументом, но функция имеет доступ к его полям. Обратите внимание на то, что функция не возвращает значения. Результат автоматически присваивается объекту dist3.

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

В качестве примера рассмотрим предыдущую программу, в которой вместо первых трёх операторов в главной функции запишем следующие:

Distance d1(11, 6.25); // вызывает конструктор с двумя аргументами

Distance d2(d1); // вызывает конструктор копирования

Distance d3 = d1; // вызывает конструктор копирования

Действие конструктора копирования сводится к копированию значений полей объекта d1 в соответствующие поля объектов d2 и d3. Оба оператора выполняют одинаковые действия (вызывают конструктор копирования по умолчанию) и равноправны в использовании.

Д/З

Создайте класс Int, имитирующий стандартный тип int. Единственное поле этого класса должно иметь тип int. Создайте: а) конструкторы, которые будут устанавливать значение поля, равным нулю, инициализировать его целым значением; б) метод для вывода значения поля на экран, метод для ввода значения пользователем и метод для сложения двух значений типа Int. Напишите программу для проверки класса.

Ответ

class Int {

private:

int i;

public:

Int() { i=0; }

Int(int I) { i = I; }

void getdata() {

cout << "\nVvedite celoe chislo: "; cin >> i;

}

void add(Int a1, Int a2) {

i = a1.i + a2.i;

}

void show() {

cout << i;

}

};

//---------------------------------------------------------------------------

int main() {

Int i1(7), i2, i3;

i2.getdata();

i3.add(i1, i2);

cout << "\n i3 = "; i3.show();

getch(); return 0;

}