вторник, 28 апреля 2015 г.

Классы в С/С++: Делай с нами! Шаг 3.

Итак, продолжаю решать задачу:
Моя задача очень похожа на ваши:
"Описать класс круг с центром в точке (х0,у0) и радиусом R. Методы: расчет периметра и площади. Друг класса определяет, пересекаются ли два круга."

На этом шаге займемся другом класса.

1.На первом этапе обдумаем, что делает друг класса, какие данные для этого нужны, какие результаты получаются и будем ли их передавать в main. Обычно друг класса пишется для работы с несколькими объектами - экземплярами класса и ему доступны все данные каждого объекта (чем он и удобен).
В разбираемой задаче  друг класса определяет, пересекаются ли два круга. Следовательно, имена этих объектов должны быть параметрами функции-друга. Обозначим эти имена как о1 и о2. Друг будет вычислять расстояние между объектами-кругами, сравнивать это расстояние с радиусами и задавать значение целой переменной-флага : если круги пересекаются, она будет равна 1, а если нет -0. Это значение будем возвращать  в main с помощью имени функции-друга. Поэтому объявим тип имени друга как целый.

2. Добавим объявление друга класса. Это делается также, как объявление функций, членов класса, но с добавлением слова friend.
class Krug
{
    float x,y,R,P,S;
    public:
    Krug(float x0,float y0,float R0);
    float Perimetr(void);
    float Plosh(void);
    void Show(void);
friend int Peresech(Krug &, Krug &);
};

3.Начинаем писать код функции-друга (например, в том же файле, где описаны функции класса). Сначала напишем заголовок  и часть кода (вычислим расстояние между кругами). Поставим печать и формально передадим результат:

int Peresech(Krug & o1, Krug & o2)
{   float rr;
    rr=sqrt(pow(o1.x-o2.x,2)+pow(o1.y-o2.y,2));
    cout<<"* rr="<<rr<<endl;
    return 0;
}
Здесь о1, о2 -имена объектов-кругов, с которыми работает друг.  o1.x -обращение к переменной х  объекта о1.

4.Вызовем  функцию-друга в main:
flag=Peresech(o1,o2);
if(flag) cout<<" o1 - o2 peresekajutsja"<<endl;
Построим проект.

5.Если ошибок нет, допишем функцию-друга до конца.
 int Peresech(Krug & o1, Krug & o2)
{   float rr;
    rr=sqrt(pow(o1.x-o2.x,2)+pow(o1.y-o2.y,2));
    cout<<"* rr="<<rr<<endl;
    if((rr<=o1.R+o2.R)&&(o1.R<=rr+o2.R)&&(o2.R<=rr+o1.R)) return 1;
    else return 0;
}
 - круги пересекаются только если расстояние между ними и их радиусы образуют треугольник.

и подберем несколько кругов для проверки:

#include "Kl.h"
void main()
{
Krug o1(2,0,2),o2(3,0,2),o3(3,0,3),o4(3,0,4);
int flag;
o1.Show();
o2.Show();
float p1,p2;
p1=o1.Perimetr();
p2=o2.Perimetr();
cout<<"p1= "<<p1<<endl;
cout<<"p2= "<<p2<<endl;
flag=Peresech(o1,o2);
if(flag) cout<<" o1 - o2 peresekajutsja"<<endl;
if(Peresech(o1,o3)) cout<<" o1 - o3 peresekajutsja"<<endl;
if(Peresech(o1,o4)) cout<<" o1 - o4 peresekajutsja"<<endl;
}

6. То, что сделано с помощью функции-друга, можно сделать без него.
Это можно сделать двумя способами:
-открыть доступ к членам- данным класса и обращаться к ним напрямую. Но, как уже говорилось, это делать категорически не рекомендуется для защиты данных;
-написать члены-функции, возвращающие члены-данные и использовать их. Такой пример описан здесь.

Комментариев нет:

Отправить комментарий