Лабораторная работа №4-5

Тема: Разновидности конструкторов, атрибуты и методы доступа к членам классов, перегрузка функий. Преобразования типов. Перегрузка операторов. Использование аппарата дружественных функций (для С++).

Цель:

- познакомиться с дружественными функциями и перегрузкой операторов;

- научиться создавать программы на С++ с использованием различных видов конструкторов;

- уметь использовать аппарат дружественных функций в С++.

Краткая теория.

Примером перегруженных функций-членов класса являются конструкторы. Обычно конструкторов в каждом классе несколько. Используя перегруженные конструкторы, возможно преобразование к типу класса любых других типов данных. Например, для класса Counter применяется конструктор, преобразующий тип Example в тип Counter:

Counter{
int count;

public:
Counter(Example & e) { count = e.Value(); }

}

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

Ключевое слово friend - спецификатор функции, который дает функции- не члену класса доступ к скрытым членам класса. Он используется для того, чтобы выйти за строгие рамки типизации и сокрытия данных в С++.

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

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

Рассмотрим пример.

class complex {

double real,imag;

public:

complex(double r) { real=r; imag=0; }

void assign(double r,double i) { real=r; imag=i; }

void print() { cout << real << “+”<<imag<<”i”; }

// обеспечивает преобразование complex в double

operator double() { return sqrt(real*real+imag*imag); }

};

inline int greater(int i,int j) { return (i > j) ? i:j; }

inline double greater(double i,double j) { return (i > j) ? i:j; }

inline complex greater(complex i,complex j) { return (i > j) ? i:j; }

void main() {

int i=5,j=10;

float x=7;

double y=14;

complex w(0),z(0);

w.assign(x,y); // требует преобразования float x в double

z.assign(i,j); // оба параметра преобразуются в double

// выбирает первое определение greater по правилу соответствия

cout << greater(i,j) << endl;

// Выбирает второе определение greater, так как

// использовано стандартное расширяющее преобразование из float в double

cout << greater(x,y) << endl;

//Второе определение greater выбирается из-за точного соответствия //правилу.

cout << greater(y,double(z)) << endl;

// точно соответствует третьему определению

cout << greater(w,z) << endl;

}

Практические задания:

Перегрузка операторов

1. Создать полноценный класс "Строка", с конструкторами, деструктором, преобразованием типов (из char * в String и наоборот, перегрузкой операторов суммирования, присвоения, +=, сравнения ==, !=, отрицания !, <, >, >=, <=, индексирования [], () - возвращения подстроки.

Преобразование типов. Дружественные функции

1. Определить два класс, строку с преобразование из char * в строку и обратно и Double с преобразованием из double и обратно, а также взаимное преобразование String и Double.

2. Создать класс целых чисел Integer. Определить перегруженную функцию, возвращающую минимальное из двух аргументов. Функция не является членом класса целых чисел. Перегруженные функции имеют аргументы типа int, double, Integer. Тело перегруженных функций должны быть одинаковыми.