Форум программистов, компьютерный форум CyberForum.ru

friend классы - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
y_e_p
 Аватар для y_e_p
3 / 3 / 0
Регистрация: 15.09.2013
Сообщений: 27
25.09.2013, 00:00     friend классы #1
Доброго времени суток форумчани. Вот потихоньку учу C++, добрался до дружественных функций и классов. Вроде бы все ясно, но все равно не могу понять как оно работает?? и нужно ли вообще? Пересмотрел много примеров, но там в коде начинаешь путаться что куда идет. Объясните на несложном примере с классом и функциями пожалуйста(если можно). Реально не понимаю. Заранее спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.09.2013, 00:00     friend классы
Посмотрите здесь:

Friend Function C++
Friend класса C++
friend function C++
Класс friend C++
friend class C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
25.09.2013, 00:17     friend классы #2
Нужны для того что бы какой нить функции разрешить доступ к закрытым членам класса. От примерчик:
Есть класс А
C++
1
2
3
4
5
6
class A
{
int a;
public:
A(int aa=10):a(aa){}
};
И есть функция которая принимает переменную типа А например:
C++
1
2
3
4
void f(A a)
{
cout a.a; //будет ошибка потому что доступ к закрытым членам класса запрещен.
}
из этой функции мы не можем обратится к закрытым членам класса А (к закрытому элементу а)

Но если мы в классе А добавим строчку friend void f(A a); (в любом месте класса) например:
C++
1
2
3
4
5
6
7
class A
{
friend void f(A a);
int a;
public:
A(int aa=10):a(aa){}
};
то у нас в функции f можно уже будет обратиться к закрытому члену класса.

Просто если мы объявляем дружественную функцию, то из нее можно обращаться к закрытым элементам класса и все, так же и для классов при объявлении дружественного класса можно будет из того класса который друг можно будет обращаться к закрытым членам того класса для которого этот класс есть другом.
y_e_p
 Аватар для y_e_p
3 / 3 / 0
Регистрация: 15.09.2013
Сообщений: 27
25.09.2013, 00:50  [ТС]     friend классы #3
ninja2, тут то я понял с вашим примером, ну вот например, а если 2 класса есть,А и В???и классу А нужно использовать функцию класса В. как быть???
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
25.09.2013, 01:20     friend классы #4
Вот смотри, есть у тебя два класса. Это два совершенно разных класса, реализующие разный функционал и возможности, но при этом они являются очень близкими друг к другу, настолько близкими, что в принципе можно одному из классов дать возможность управлять другим классом полностью.
Зачем? Ну вообще, по хорошему, все методы и поля, о которые знать стороннему программисту (пользователю библиотеки) совсем не положено или даже вредно делают приватными (private) или защищёнными (protected). Но нередко возникают случаи, когда классы не родственны, но при этом чётко видна идеология зависимый класс - управляемый класс, так что наследованием вопрос не решить, но получить доступ к приватным (защищённым) членам класса тербуется. Вот для этого и существует механизм дружественных отношений. Использовать следует только при крайней необходимости, а то убьёте к чёрту всю инкапсуляцию.
К слову, вместо класса может быть отдельная функция, но это использовать ещё менее желательно, хоть и встречается чаще.
Примеры: у нас есть некий класс объектов Foo, но мы должны целиком и полностью управлять временем его жизни, причём управлять таким образом, что разрешить проблему с помощью конструкторов и деструкторов очень сложно и неудобно или даже невозможно, а также, мы хотим ументь этот класс печатать в стандартный поток,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <ostream>
 
using std::ostream;
 
class FooManager;
 
class Foo {
    friend FooManager;
    friend ostream& operator << ( ostream& os, Foo& f );
public:
    /***/
protected:
    /***/
private:
    int m_id = 0;
    Foo () {...} //приватный конструктор, чтобы исключить возможность создания экземпляров пользователем
}
 
class FooManager {
public:
    Foo& create () { //а создаём мы Foo с помощью вот этого метода
        return *( new Foo () ); //здесь мы имеем доступ к конструктору
    }
protected:
    /***/
private:
    /***/
}
 
ostream& operator << ( ostream& os, Foo& f ) {
    os << f.m_id; // печатаем идентификатор; мы имеем доступ к приватному полю m_id объекта f, поэтому компилятор ошибку не сгенерирует
}
Добавлено через 8 минут
Из возможностей разрешить эти проблемы не используя friend-отношения:
1) Менеджер - можно сделать статическое поле объекта вложенного класса Manager, который осуществляет всю чёрную работу, а в конструкторе просто кидать себя в манагер. Из минусов - не всегда очень удобно, да и код может стать крайне неперносимым: не каждый компилятор и/или платформа переварит такое.
C++
1
2
3
4
5
6
7
8
9
class Foo {
public:
    class Manager { ... };
    Foo () { m_manager.drop ( this ); }
protected:
    /***/
private:
    static Manager m_manager;
}
2) По идеи, все поля или методы, которые должны быть доступны определённому оператору вывода в поток, должны быть доступны и программисту из вне класса. Поэтому best-practice - не творить чепуху.

Добавлено через 19 минут
К слову, язык C++ очень древний и рудиментарный. Почему с него начинают изучать программирование - для меня загадка всех загадок и я очень сожалею, что я тоже начал именно с него, не смотря на потрясающие альтернативы. Во-первых, во времена создания Си++ некоторые вещи казались логичными и правильными, а некоторые - просто не имели альтернатив, а некоторые делались нарочно в угоду совместимости с другим языком - Си. Собственно, Си++ сегодня язык очень своеобразный. Он предлагает возможности иногда даже противоречащие друг другу (впрочем, некоторые ЯП кроме Си++ так тоже делают - дилемы). Собственно, в ходе эволюции Си++ и программирования в целом были разработаны целые манифесты о использовании такого монстра Си++ - code-style и coding standart - своеобразные сборники лучших практик. Многие из них серьёзно ограничивают сами возможности языка, но ограничивают оправданно. Например, одно из самых популярных ограничений - ограничение множественного наследования, которое очень сильно ограничивают возможности в построении архитиктуры и создания многократно используемого кода.
Friend-отношения один из таких рудиментов. Очень часто можно обойтись без него. Почти всегда. Очень редко возникает ситуация, когда без friend действительно не выгодно. Но даже в этом случае его стараются не использовать, а перестроить архитектуру так, чтобы friend-ов не было.
В общем, не дружелюбный язык, совсем не дружелюбный. Я уж промолчал про нархию с памятью. Если решили освоить ООП, то лучше посмотреть в сторону Java, Python или даже ECMAScript (JavaScript). Или на ruby, например. В общем, не советую начинать с Си++. Даже если просто посмотреть популярности форумов, то можно найти любопытное наблюдение - раздел "Си++ для начинающих" наиболее популярный из всех по количеству топикстартов в день.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
25.09.2013, 01:28     friend классы #5
Цитата Сообщение от y_e_p Посмотреть сообщение
тут то я понял с вашим примером, ну вот например, а если 2 класса есть,А и В???и классу А нужно использовать функцию класса В. как быть???
из класса B ты не сможешь использовать закрытые члены и функции класса А, если класс B не будет другом класса А.
В классе А пропиши строчку friend class B; и ты уже можешь обращаться к закрытым членам и методам из класса маленький примерчик приведу.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A
{
void print(){cout <<"class A"<<endl;
public:
A(){}
};
 
class B
{
A* p;
public:
B():p(0){}
void print__B()
{
p->print();//нельзя потому что класс B не друг класса А и функция A::print() закрытый член
//нужно добавить friend class B; тогда можно будет использовать.
}
};
y_e_p
 Аватар для y_e_p
3 / 3 / 0
Регистрация: 15.09.2013
Сообщений: 27
25.09.2013, 01:39  [ТС]     friend классы #6
AnyOne697, я то кодер на java,пишу под android,но как поступил после колледжа в политех, сразу дали тему на курсовую,а так как мне просто нужно её сдать, начал вспоминать и пополнять память по С++, много чего не привычно, и надо все осваивать в короткие сроки, поэтому обращаюсь к людям знающим на форуме, так как иногда автор в книге пишет все очень заумно, очень тяжело уловить суть, теперь я понял что к чему, благодаря вам. спасибо.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.09.2013, 07:45     friend классы
Еще ссылки по теме:

Классы. Программирование алгоритмов с использованием конструктора, деструктора, friend - функции инициализации set() и функции вывода результатов prin C++
C++ Классы. Программирование алгоритмов с использованием конструктора, деструктора, friend - функции инициализации set() и функции вывода результатов pri
C++ класс Friend

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
25.09.2013, 07:45     friend классы #7
Цитата Сообщение от y_e_p Посмотреть сообщение
AnyOne697, я то кодер на java,пишу под android,но как поступил после колледжа в политех, сразу дали тему на курсовую,а так как мне просто нужно её сдать, начал вспоминать и пополнять память по С++, много чего не привычно, и надо все осваивать в короткие сроки, поэтому обращаюсь к людям знающим на форуме, так как иногда автор в книге пишет все очень заумно, очень тяжело уловить суть, теперь я понял что к чему, благодаря вам. спасибо.
Ну раз так, вопрос снимается. Хотя он скорее безадрессный. Если сравнивать с java, C++ действительно немного сложен и часто вызывает только сомнения. Впрочем, можно использовать его почти как java - реализаций умных указателей море, с GC и без GC, стандартная библеотека весьма обширна. А сейчас в C++ есть такое, что даже в java принимали со скрипом - лямбды. Хотя, что в java, что в C++ - суть одна - создаётся анонимный класс-функтор и тут же инициализируется (Си++) или реализуется функциональный интерфейс.
Yandex
Объявления
25.09.2013, 07:45     friend классы
Ответ Создать тему
Опции темы

Текущее время: 17:39. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru