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

friend классы - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Опять тестовая оболочка - рандом http://www.cyberforum.ru/cpp-beginners/thread961727.html
Написала тест, спасибо Культину, но преподавателя не устраивает. Нужно считывать вопросы с файла с помощью рандома. В тесте 50 вопросов, выбираем их количество а потом генерируем номер каждого...
C++ Создание и использование классов.Работа над ошибками Задали сделать програмку. Вроде бы ничего сложного. Но выбивает ошибки( 1. Дано действительное число a и целое n. Вычислить сумму 1/a+1/a*(a+1)*(a+2) + 1/(a*(a+1)*(a+2)+...+(a+n)) составила... http://www.cyberforum.ru/cpp-beginners/thread961725.html
Преобразование C++
О каком преобразовании идет речь в строке 34, если конструктор принимает тип double и аргумент (10.0) записывается в double dReal? // // TypeConversion - demonstrate the implicit conversion // ...
C++ типы данных
Подскажите как средствами С++ получить доступ к отдельным байтам стандартных типов данных, только без использования асматических вставок.
C++ Мусор в памяти, выделенной динамически http://www.cyberforum.ru/cpp-beginners/thread961704.html
Есть код, выполняет разархивацию файла, закодированного LZ77. Вот его основная часть: цикл в котором проверяется каждый бит в маске и согласно его значению раскодируется файл. Если бит установлен в...
C++ оператор delete #include <iostream> #include <clocale> #include <iomanip> using namespace std; int main() { setlocale (LC_ALL,"russian"); struct kniga { char* name ; char* autor ; подробнее

Показать сообщение отдельно
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
25.09.2013, 01:20
Вот смотри, есть у тебя два класса. Это два совершенно разных класса, реализующие разный функционал и возможности, но при этом они являются очень близкими друг к другу, настолько близкими, что в принципе можно одному из классов дать возможность управлять другим классом полностью.
Зачем? Ну вообще, по хорошему, все методы и поля, о которые знать стороннему программисту (пользователю библиотеки) совсем не положено или даже вредно делают приватными (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, например. В общем, не советую начинать с Си++. Даже если просто посмотреть популярности форумов, то можно найти любопытное наблюдение - раздел "Си++ для начинающих" наиболее популярный из всех по количеству топикстартов в день.
2
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru