Дружественные функции / класс C ++ использует?

Каково реальное использование функции / класса друга в C ++? Не могли бы вы привести пример, где только friend является правильным подходом?

Спасибо


person Sanish Gopalakrishnan    schedule 23.12.2011    source источник
comment
Видите эти вопросы в правой части страницы? Щелкните несколько из них. Они актуальны.   -  person Blender    schedule 23.12.2011
comment
Да, здесь есть хороший: stackoverflow.com/questions/17434/. Мне следовало провести дополнительное исследование, прежде чем задавать свой вопрос, извините :-(   -  person Sanish Gopalakrishnan    schedule 23.12.2011
comment
Расширение общедоступного интерфейса и связь с документацией: programmers.stackexchange.com/a/99595/12917   -  person Martin York    schedule 23.12.2011
comment
В отличие от врагов - нужно держать друзей ближе. Держитесь подальше от друзей и не доверяйте им свои активы (кстати, это была метафора для американцев здесь)   -  person Ed Heal    schedule 23.12.2011


Ответы (3)


«В C ++ только ваши друзья могут получить доступ к вашим личным частям».

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

person Charlie Martin    schedule 23.12.2011
comment
Вы должны приехать из Калифорнии ?! - person Ed Heal; 23.12.2011
comment
Ох уж эти классы! Всегда экспериментирую со своими друзьями! (Ваша цитата заставила меня на самом деле смеяться) - person Corbin; 23.12.2011
comment
Я использую это, так как я преподавал C ++ 15 лет назад, и он всегда был любимым. Спасибо. - person Charlie Martin; 23.12.2011
comment
@EdHeal Почему? (На самом деле я из Колорадо, но жил в Калифорнии.) Разрешают ли люди за пределами Калифорнии доступ к своим личным частям тем, кто не их друг? - person Charlie Martin; 23.12.2011
comment
@pinkpanther - это британский юмор. - person Ed Heal; 23.06.2013
comment
@EdHeal lol .... Я спрашиваю ... какая связь между его ответом и Калифорнией ....: :) - person pinkpanther; 23.06.2013
comment
Смысл друга в том, что вы можете упаковать свое программное обеспечение в более мелкие группы - очень хипповское занятие ?! - person Ed Heal; 23.06.2013

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

friend const X operator+(const X&, const X&);

inline const X operator+(const X& arg1, const X& arg2)
{
    X r;
    r.x = arg1.x + arg2.x;
    return r;
}

Но главное - это их способность получать доступ к приватным данным двух разных классов.

person Yola    schedule 23.12.2011

Использование friend на самом деле очень не рекомендуется в C ++ (это как бы нарушает всю идею инкапсуляции), но мне приходит в голову пример, когда только друг является правильным подходом:

friend ostream & operator<< (ostream & out, const MyClass & C);
friend istream & operator>> (istream & in, MyClass & C);
person juliomalegria    schedule 23.12.2011
comment
Почему с операторами ввода и вывода все по-другому? Если вы собираетесь дать пользователю возможность читать / записывать данные класса из / в поток, почему бы не предоставить им общедоступные средства доступа к данным? Тогда операторам не нужно дружить, так как они могут вызывать публичные аксессоры. - person Benjamin Lindley; 23.12.2011
comment
дружба увеличивает инкапсуляцию. - person Martin York; 23.12.2011
comment
существует множество случаев, когда вы хотите, чтобы класс имел поведение iostream, но вы не хотите предоставлять публичные методы доступа к некоторым атрибутам. Это может звучать противоречиво ... потому что это так, и поэтому friend не приветствуется. - person juliomalegria; 23.12.2011
comment
@LokiAstari: как дружба может увеличить инкапсуляцию? Это уменьшает инкапсуляцию с любой точки зрения. Инкапсуляция означает ограничение доступа к некоторым компонентам классов. Используя friend, вы игнорируете эту ограниченную часть класса, поэтому это противоречит инкапсуляции. - person juliomalegria; 23.12.2011
comment
@ julio.alegria: -1 от меня. Совершенно не согласен с тем, что дружба не приветствуется (и если вы поищете на этом сайте дружбу с C ++, вы обнаружите, что консенсус не согласуется с вашим утверждением о том, что она снижает инкапсуляцию: stackoverflow.com/questions/1093618/). Но не думайте, что вы должны использовать его для всего (как и для всех языковых функций, которые используются по мере необходимости). - person Martin York; 23.12.2011
comment
@ julio.alegria: увеличивает инкапсуляцию, потому что снижает потребность в раскрытии вашей внутренней реализации в целом. Несмотря на то, что вы открываете внутреннее устройство своим друзьям (и, таким образом, тесно связываете себя со своим другом), это уменьшит необходимость раскрывать вашу внутреннюю реализацию не друзьям (то есть людям, которые не являются частью вашего публичного интерфейса), это снижает общую взаимосвязь и, следовательно, увеличивает инкапсуляцию. - person Martin York; 23.12.2011
comment
@LokiAstari Я думаю, что мы должны различать концепцию инкапсуляции ООП и концепцию витой инкапсуляции C ++ (не то же самое, не то же самое). В концепции инкапсуляции ООП никто, кроме класса, не может получить доступ к его атрибутам, поэтому, следуя этой концепции, friend плохо, очень плохо для инкапсуляции. - person juliomalegria; 23.12.2011
comment
@ julio.alegria: По общему мнению в сообществе C ++, это хорошо для инкапсуляции. Ответы с наивысшими баллами на большинство вопросов подтверждают это: stackoverflow.com/a/734114/14065 stackoverflow.com/a/1093681/14065 stackoverflow. com / a / 17443/14065 stackoverflow.com/a/17505/14065 - person Martin York; 23.12.2011
comment
@LokiAstari Я собираюсь использовать здесь клише: мы согласны не соглашаться - person juliomalegria; 23.12.2011
comment
Использование друга на самом деле очень не рекомендуется в C ++ Неправильно. - person curiousguy; 23.12.2011
comment
@ julio.alegria: дружественные функции уменьшают инкапсуляцию. Но точно так же, как общедоступные методы уменьшают инкапсуляцию. Между ними нет разницы. - person Martin York; 23.12.2011
comment
@curiousguy Нет, это показывает, что между разработчиками программного обеспечения существуют разногласия; это никоим образом не означает, что это какой-то культ вуду. - person Alice; 29.07.2014
comment
Инкапсуляция @Alice на самом деле является культом вуду. - person curiousguy; 30.07.2014
comment
@curiousguy Пожалуйста, объясните, почему широко распространенная и принятая практика является вудуской или культовой. - person Alice; 02.08.2014
comment
@Alice Это долгая история. Для начала, все примеры инкапсуляции (комплексные числа) в учебниках неверны; ты ничего этого не хочешь. В общем, строительные кирпичи должны показывать, как они работают. Вы хотите, чтобы ваш строковый класс раскрыл тот факт, что он использует refcount, или что это не так. Вы не хотите непредсказуемых выступлений. Это базовая инженерия. Инструменты должны документировать поведение и характеристики. Скрывать спектакль очень неправильно. CS - это не математика. Производительность имеет значение. Существенные изменения в реализации строительного блока неверны. - person curiousguy; 02.08.2014
comment
@curiousguy Ваши утверждения не просто неверны; они категорически таковы. ADT не должен раскрывать принцип работы, он должен просто раскрывать свою алгоритмическую сложность (желательно в Big O). Основной факт инженерной мысли заключается в том, что новые техники приходят с пугающей регулярностью. Предоставляя только необходимую и достаточную информацию, можно легко заменить новые и лучшие алгоритмы, когда они будут обнаружены. Предсказуемая производительность не имеет ничего общего с раскрытием ненужной информации; вот почему у нас есть формализации, такие как математика O. CS IS, точно так же, как геометрия. - person Alice; 02.08.2014
comment
@Alice новые техники приходят с пугающей регулярностью, вы можете назвать один? - person curiousguy; 02.08.2014
comment
@curiousguy Позвольте мне назвать несколько: списки пропуска (1990 г.), развернутые связанные списки (1994 г.), сортировка по воронке (1999 г.), мягкие кучи (2000/2009 г.), распределенные хеш-таблицы (2001 г.), тест простоты AKS (2002 г.), блок цепочки (2009), параллельные генераторы случайных чисел на основе счетчиков (2011), ctries (2011), HElib (гомоморфное шифрование, 2013), разреженное быстрое преобразование Фурье (2012-2014). Если мы хотим включить различные небольшие улучшения, внесенные в структуры данных и алгоритмы, я бы сказал, что применимы также массивы Джуди, версии структур со свободными блокировками, а также постоянные улучшения веревок, деревьев пальцев и хеш-таблиц. - person Alice; 02.08.2014
comment
@curiousguy Многие из этих структур выигрывают от использования в качестве ADT или общих алгоритмов; Сортировка по воронке - это алгоритм сортировки даже для умеренно больших списков, развернутые связанные списки и списки пропуска - это отбрасываемые замены, которые предлагают те же алгоритмические границы, но могут быть намного быстрее или меньше, SFFT ускоряет многие распространенные FFT, Свободные от замков конструкции и веревки дают преимущества и т. д. Но если строительные блоки раскрывают принцип их работы, вы не сможете легко добавить новые конструкции. В этом суть инкапсуляции: предоставление заменяемого и масштабируемого интерфейса. - person Alice; 02.08.2014
comment
@Alice Гомоморфное шифрование - это замена чему? Сортировка воронки влияет на ADT, как? Структуры без замков заменяют замки? - person curiousguy; 02.08.2014
comment
@curiousguy Сортировка по воронке - это алгоритм; алгоритмы запускаются через ADT. Вы просили новые техники; не все они ADT. Хорошая работа: собрать вишню, а затем напасть на соломенного человека. - person Alice; 02.08.2014