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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
y_e_p
3 / 3 / 0
Регистрация: 15.09.2013
Сообщений: 27
#1

friend классы - C++

25.09.2013, 00:00. Просмотров 2500. Ответов 6
Метки нет (Все метки)

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

Перегрузка операторов, friend или нет friend? - C++
Всем здравствуйте. Есть такой вопрос: при перегрузке операторов в классе(пусть будут + и = (вообще неважно, за исключением потока)) как и...

Friend для friend - C++
всем доброго времени суток, покажу проблему на примере: Class B; class A{ int F; friend B; public: A(){F=0;}; };

Не работает friend - C++
#ifndef INTEGERLONGS_HPP_INCLUDED #define INTEGERLONGS_HPP_INCLUDED...

класс Friend - C++
Подскажите в каких случаях лучше использовать класс friend? Известно что класс friend нарушает принцип инкапсуляции, так почему же мы его...

Friend function - C++
Нужно сделать функции Length и Angle френдовыми для другого класса. Как это запилить? Sect.h #include <iostream> #include <math.h> ...

Класс friend - C++
Проблемка с доступом через дружественный класс: class Game { friend Player; //тут объявлен класс-друг ...

Friend Function - C++
Я не очень понимаю как пользаватса Friend функцыей Class.h #include <stdio.h> #include "iostream" using namespace std; ...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
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
3 / 3 / 0
Регистрация: 15.09.2013
Сообщений: 27
25.09.2013, 00:50  [ТС]     friend классы #3
ninja2, тут то я понял с вашим примером, ну вот например, а если 2 класса есть,А и В???и классу А нужно использовать функцию класса В. как быть???
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
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
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
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 function - C++
Помогите плз разобраться: Когда я делаю инкремент &quot;х&quot; через закрытые функции класса - все работает нормально, а когда через...

Friend-функции - C++
из теории ясно, что friend функция — это функция, которая не является членом класса, но имеет доступ к членам класса, объявленным в полях...

friend function - C++
После добавления дружественной ф-ции sum( а она для сложения salary у человека, которого я выберу) класс перестал работать. Что у меня не...

Friend класса - C++
#include &lt;iostream&gt; class assoc { struct pair { char* name; int val; }; int free;

friend class - C++
#include &lt;iostream&gt; using namespace std; #include &lt;string&gt; using std::string; class two; class one { friend...


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

Или воспользуйтесь поиском по форуму:
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
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 классы
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru