Double Dot :: Dist ( Dot В ) const
Программа вычисляет координаты третьей вершины и площадь правильного треугольника Программа составлена студентом группы 3351 Незнайкой О.К. Введите координаты точки A x=0 y=0 Введите координаты точки B x=2 y=0 Проекции вектора AB: x = 2 y = 0 Проекции вектора AC: x = 1 y = 1.73205 Координаты точки C: x = 1 y = 1.73205 Sabc = 1.73205 Углы треугольника: BAC = 60° CBA = 60° ACB = 60° Стороны треугольника: AB = 2 AC = 2 BC = 2 Продолжить? (Y/N) ЛЕКЦИЯ 4 ДРУЖЕСТВЕННЫЕ ФУНКЦИИ_____________________________________________________ 1 Функции, дружественные одному классу_______________________________________________________ 1 Функции, дружественные нескольким классу___________________________________________________ 3 Функции-члены, дружественные другому классу ________________________________________________ 4 ДРУЖЕСТВЕННЫЕ КЛАССЫ_______________________________________________________ 5 Скажи мне кто твой друг, и я скажу, кто имеет доступ к твоим закрытым данным. Народная пословица Концепция инкапсуляции данных - одна из основополагающих концепций ООП. C++ предоставляет возможность обойти эту концепцию с помощью дружественных функций. Однако использовать ее без веских причин не стоит. C++ позволяет объявлять два вида друзей класса: дружественную функцию или дружественный класс. ДРУЖЕСТВЕННЫЕ ФУНКЦИИ Функции, дружественные одному классу Обычный способ доступа к закрытым членам класса - использование открытой функции-члена. Однако C++ поддерживает и другой способ получения доступа к закрытым членам класса - с помощью дружественных функций. Дружественные функции не являются членами класса, но имеют доступ к его закрытым членам. Более того, одна такая функция может иметь доступ к закрытым членам нескольких классов. Чтобы объявить функцию дружественной некоторому классу, в определение этого класса включают ее прототип, перед которым ставится ключевое слово friend. Приведем пример: Файл Doth { // закрытые члены класса const char name; // имя точки double x, у; // координаты точки public: // открытые члены класса // конструкторы Dot (char Name): name (Name) { x = 0; у = 0; } Dot (char Name, double X, double Y): name (Name) { x = X; у = Y; } // inline функции получения и задания координат inline double GetX () const { return x; } inline double GetY () const { return у; } inline void SetX (double X) { x = X; } inline void SetY (double Y) { y = Y; } // выводит на экран имя и координаты текущей точки void Print () const; // возвращает значение расстояния между текущей и заданной точками double Dist (Dot В) const; // возвращает значение расстояния между двумя заданными точками friend double Dist (const Dot & A, const Dot & В); }; // возвращает значение расстояния между двумя заданными точками double Dist (Dot* pA, Dot* pB); // функция получает указатели на точки // возвращает значение площади треугольника с заданными вершинами double Area (const Dot & A, const Dot & В, const Dot & С); Файл Dot.cpp double Dot:: Dist (Dot В) const { double X = В. x - x; // объявляет и вычисляет double Y = В. у - у; // катеты прямоугольного треугольника return sqrt (X*X + Y*Y); // вычисляет и возвращает значение } // гипотенузы прямоугольного треугольника Объектно-ориентированное программирование Лекция 4 Дружественные функции и классы
// объявляет и вычисляет // катеты прямоугольного треугольника // вычисляет и возвращает значение
// гипотенузы прямоугольного треугольника // объявляет и вычисляет // катеты прямоугольного треугольника // вычисляет и возвращает значение // гипотенузы прямоугольного треугольника , const Dot & C) // объявляет и вычисляет // длины сторон треугольника
// объявляет и вычисляет длину полупериметра // вычисляет по формуле Герона площадь // треугольника и возвращает её значение Файл Main.cpp // вызов конструктора Dot(char Name, double X, double Y) // вызов конструктора Dot (char Name) // вызов функции Dist (Dot & A) const // вызов функции Dist (const Dot & A, const Dot & B) cout<<S<<"AC = "<<Dist (&A, &C)<<'\n'; // вызов функции Dist (Dot* pA, const Dot* pB) CharToOem ("Площадь треугольника ", S); cout<<S<<"ABC = "<<Area (A, B, C)<<'\n'; } В приведённом примере объявлен класс точки Dot и решается задача вычисления расстояния между двумя точками. Задача решена тремя различными способами. Функция double Dot:: Dist (Dot B) const является членом класса Dot и возвращает значение расстояния между текущей и заданной точками. Спецификатор const указывает компилятору, что состояние текущего объекта не должно изменяться. В качестве параметра функция получает целиком объект типа Dot, который занимает в памяти 17 байт. Функция-член класса вызывается оператором: A. Dist (B), где объект А является текущим, а объект В – параметром. Функция friend double Dist (const Dot & A, const Dot & B) возвращает значение расстояния между двумя заданными точками. Спецификатор const перед параметрами указывает компилятору, что состояние параметров не должно изменяться. В качестве параметров функция получает две ссылки на объекты типа Dot, которые занимает в памяти по 4 байта каждый. Функция вызывается оператором Dist (A, B). Поскольку функция является дружественной классу Dot, то доступ к закрытым членам x и y параметров A и B, которые являются объектами типа Dot, осуществляется с помощью оператора точка, например: A. x. Функция double Dist (Dot* pA, Dot* pB) возвращает значение расстояния между двумя заданными точками. В качестве параметров функция получает два указателя на объекты типа Dot, которые занимает в памяти по 4 байта каждый. Функция вызывается оператором Dist (&A, &B). Поскольку функция не является ни членом класса Dot, ни дружественной классу к нему, то не может получить доступа к закрытым членам x и y параметров A и B. Получить значения членов x и y в этом случае можно только с помощью открытых функций-членов класса GetX () и GetY () соответственно, например: pA->GetX (). Обратите внимание на то, что прототип глобальной функции мы расположили за пределами объявления класса. Использование указателей и ссылок на объекты в качестве параметров функции вместо объектов уменьшает объём памяти, резервируемой функцией, и время её вызова. Приведённый выше пример содержит также решение задачи вычисления площади треугольника с помощью глобальной функции double Area (const Dot & A, const Dot & B, const Dot & C), которая получает три ссылки на точки и возвращает значение площади треугольника. Функция вызывается операто- Объектно-ориентированное программирование Лекция 4 Дружественные функции и классы ром Area (A, B, С). Несмотря на то, что функция использует объекты типа Dot, тело функции не содержит обращений к закрытым членам класса. Поэтому мы не стали объявлять функцию как дружественную. Дружественная функция не является членом класса, в котором она объявлена. Поэтому, вызывая дружественную функцию, не нужно указывать имя объекта или указатель на объект и операцию доступа к члену класса (точку или стрелку). Доступ к закрытым членам класса дружественная функция получает только через объект класса, который, в силу этого, должен быть либо объявлен внутри функции, либо передан ей в качестве аргумента. Дружественная функция не наследуется, то есть она не является таковой для производных классов.
|