Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lections_rus.doc
Скачиваний:
31
Добавлен:
06.02.2016
Размер:
1.41 Mб
Скачать

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

Проверим, как же работают дружественные функции, объявленные внутри класса.

#include <iostream.h>

class A //интерфейс (протокол) класса A

{

private:

int pole;

public:

A(){ //конструктор по умолчанию

pole=55;//инициализация закрытой переменной

//выведем на экран сообщение, что конструктор отработал

cout<<"Constructor A\n";

}

//объявление дружественной функции которая принимает экземпляр класса A

friend void ourfriend(const A &f);

};

//раз объявили дружественную функцию, то давайте уже и реализуем ее

void ourfriend(const A &f)

{

//итак, для демонстрации работы дружественной функции, мы обратимся

//к закрытой переменной pole экземпляра класса f и выведем ее значение на экран.

cout<<"\nWow! We have free access to private members,\n";

cout<<"pole ="<<f.pole<<endl;

}

void main()

{

A example; //создали экземпляр класса А - example

ourfriend(example); //собственно тестирование дружественной функции

}

Результат выполнения программы:

Constructor A

Wow! We have free access to private members,

pole =55

Итак, мы смогли получить доступ к закрытой переменной класса из функции (которая, при этом, не является членом класса), используя механизм дружественных функций. Заметим, что при работе с дружественной функцией следует помнить о том, что она не имеет указателя thisкласса, в котором она объявлена как дружественная. Почему?.. Ответ мы найдем в самом смысле использования дружественных функций: дружественная функция не является членом этого класса.

Если все функции-члены одного класса являются дружественными функциями другого класса, то это можно записать как:

friend class имя_класса;

Может ли функция быть дружественной нескольким классам? Да, но тогда надо добавить ее описание во все классы, к внутренним данным которых будет производиться обращение. А как же быть с защищенностью данных, если можно получить доступ к данным напрямую?Не волнуйтесь, с точки зрения использования механизма инкапсуляции (напомним, под этим понятием мы подразумеваем сокрытие данных),защищенность данных сохраняется, поскольку в дружественных функциях мы свободно работаем только с экземплярами данного класса, но не с самим классом.

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

#include <iostream.h>

class A //интерфейс (протокол) класса A

{

public:

A(){ //конструктор по умолчанию

cout<<"Constructor A\n";//конструктор отработал

}

//функция-член FriendToB() будет использоваться как

//дружественная функция для класса B

void FriendToB();

void SomeFunction();

};

class B //интерфейс (протокол) класса B

{

private:

int i,j; //наши "подопытные" закрытые переменные;

//если сможем обратиться к этим переменным

//из дружественной функии FriendToB(), то "опыт удался"

public:

B(){

i=10; //произведем инициализацию

j=17;

cout<<"Constructor B\n";//конструктор отработал

}

//укажем, что класс B имеет дружественную функцию, которая

//является функцией-членом класса A

friend void A::FriendToB();

};

class C

{

private:

int k,n;

public:

C(){

k=4; //начальная инициализация

n=7;

cout<<"\n\nConstructor C\n";//конструктор отработал

}

C(int kl,int nl){k=kl; n=nl;}

C operator+(C c1) // перегрузка оператора +

{

C temp(k+c1.k, n+c1.n);

return temp;

}

//укажем что ВСЕ функции-члены класса A, являются

//дружественными для даного класса

friend class A;

};

//действительно ли может функция-член одного

//класса обращаться к закрытым данным другого класса. Давайте проверим!

void A::FriendToB()

{

B example; //объявим экземпляр класса B

cout<<"So, variables' value are:\n";

//и произведем доступ к закрытым данным

cout<<"example.i="<<example.i;

cout<<"\nexample.j="<<example.j<<endl;

}

//действительно ли после объявления в классе С friend class A; -все функции-члены //класса A станут дружественными функциями для класса С?

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

void A::SomeFunction()

{

C temp; //объявим экземпляр класса С

C temp1(10,10);

temp=temp+temp1; // доступ к функции класса С

cout<<"And now we are testing friend class...\n";

//и произведем доступ к закрытым данным

cout<<"temp.k="<<temp.k;

cout<<"\ntemp.n="<<temp.n<<endl;

}

void main()

{

A test; //создали экземпляр класса А - example

//собственно тестирование дружественной функции классу B

test.FriendToB();

//проверим, все ли функции-члены класса A являются дружественными

//классу С (на примере, функции SomeFunction)

test.SomeFunction();

}

Вот что будет выведено на экран, в результате выполнения программы:

Constructor A

Constructor B

So, variables' value are:

example.i=10

example.j=17

Constructor C

And now we are testing friend class...

temp.k=4

temp.n=7

Итак, если функция или функция-член объявлены как дружественные, то такие функции или функции-члены такого класса могут осуществлять непосредственный доступ ко всем (private, protected, public)данным (полям-данным и функциям-членам) класса, для которого они дружественны.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]