friend
От: Hоmunculus  
Дата: 15.11.25 02:14
Оценка: +1 :)
Как считаете — friend это костыль для кривой архитектуры или норм?
Re: friend
От: so5team https://stiffstream.com
Дата: 15.11.25 05:13
Оценка: +4
Здравствуйте, Hоmunculus, Вы писали:

H>Как считаете — friend это костыль для кривой архитектуры или норм?


Вопрос из категории "а пищевая соль полезна или вредна?"
С таким же банальным ответом: все зависит о количества.
Re: friend
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.11.25 09:36
Оценка: +4
Здравствуйте, Hоmunculus, Вы писали:

H>Как считаете — friend это костыль для кривой архитектуры или норм?


Иными словами, потребность/возможность локализовать видимость внутри группы связанных, но не родственных, классов (а не глобально/локально/в пределах файла) — это костыль для кривой архитектуры или норм?

Вот, C++ дал тебе дополнительную возможность управления областью видимости. Вопрос в том, как ты ей воспользуешься. Любым другим способом можно распорядиться разумно или безумно, так вот и этим.
Re[2]: friend
От: Hоmunculus  
Дата: 15.11.25 09:52
Оценка: :)
Здравствуйте, Pzz, Вы писали:

Ну смотри. Есть какое-то приватное поле. Никто не должен ничего о нем знать. Вот никто. Это суть этого поля. Оно просто как-то там работает. А тут класс говорит — вот это мой друг. Все. Друг может ВСЕ!!! Это правильно?

Это все равно что, ну например, кишки и зубы. Это приватные поля человека. Никого нельзя пускать то трогать. Но ты приходишь к зубному и разрешаешь ему доступ к зубам. При этом бац!!! Он может вполне что-то сделать с твоими кишками. Это как? Норм?

Наверное более правильно уж если и разрешать, то не всегда и не ко всему. Нет?
Re: friend
От: Великий Мессия google
Дата: 15.11.25 10:09
Оценка:
https://isocpp.org/wiki/faq/friends#friends-and-encap
https://google.github.io/styleguide/cppguide.html#Friends
Re[3]: friend
От: Qulac Россия  
Дата: 15.11.25 10:33
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Здравствуйте, Pzz, Вы писали:


H>Ну смотри. Есть какое-то приватное поле. Никто не должен ничего о нем знать. Вот никто. Это суть этого поля. Оно просто как-то там работает. А тут класс говорит — вот это мой друг. Все. Друг может ВСЕ!!! Это правильно?


H>Это все равно что, ну например, кишки и зубы. Это приватные поля человека. Никого нельзя пускать то трогать. Но ты приходишь к зубному и разрешаешь ему доступ к зубам. При этом бац!!! Он может вполне что-то сделать с твоими кишками. Это как? Норм?


H>Наверное более правильно уж если и разрешать, то не всегда и не ко всему. Нет?


Объявление друга происходит в самом классе, т.е. нельзя написать класс и объявить его другом другого класса, т.е. инкапсуляция не нарушается. Другое дело, что это делает класс "кособоким"
Программа – это мысли спрессованные в код
Re[4]: friend
От: Hоmunculus  
Дата: 15.11.25 10:33
Оценка:
Здравствуйте, Qulac, Вы писали:

Я в курсе
Re[3]: friend
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.11.25 10:39
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Ну смотри. Есть какое-то приватное поле. Никто не должен ничего о нем знать. Вот никто. Это суть этого поля. Оно просто как-то там работает. А тут класс говорит — вот это мой друг. Все. Друг может ВСЕ!!! Это правильно?


Вот смотри, есть два класса. Которые, так уж получилось, выниждены знать про внутреннее устройства друг друга.

Слово friend позволяет выразить эту мысль, не делая поля и методы, через которые эти классы взаимодействуют, публичным достоянием.

Строгое ООП, это, наверное, хорошо. Но реальная жизнь не всегда в него укладывается.

H>Это все равно что, ну например, кишки и зубы. Это приватные поля человека. Никого нельзя пускать то трогать. Но ты приходишь к зубному и разрешаешь ему доступ к зубам. При этом бац!!! Он может вполне что-то сделать с твоими кишками. Это как? Норм?


Ну вот как раз friend позволяет объявить зубного другом зубам, но не кишкам.

H>Наверное более правильно уж если и разрешать, то не всегда и не ко всему. Нет?


Ну так оно так и есть. Класс может назначить другую функцию или другой класс своим другом — позволив ему копаться в своих приватных методах и полях. Но именно ему, а не всем подряд.
Re[3]: friend
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 15.11.25 10:51
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Это все равно что, ну например, кишки и зубы. Это приватные поля человека. Никого нельзя пускать то трогать. Но ты приходишь к зубному и разрешаешь ему доступ к зубам. При этом бац!!! Он может вполне что-то сделать с твоими кишками. Это как? Норм?


Хирург иногда делает что-то подобное
Маньяк Робокряк колесит по городу
Re[4]: friend
От: Hоmunculus  
Дата: 15.11.25 10:59
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, Hоmunculus, Вы писали:


H>>Это все равно что, ну например, кишки и зубы. Это приватные поля человека. Никого нельзя пускать то трогать. Но ты приходишь к зубному и разрешаешь ему доступ к зубам. При этом бац!!! Он может вполне что-то сделать с твоими кишками. Это как? Норм?


M>Хирург иногда делает что-то подобное


Ты не понял мою мысль про зубного? Ну ок.
Re[5]: friend
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 15.11.25 11:01
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>>>Это все равно что, ну например, кишки и зубы. Это приватные поля человека. Никого нельзя пускать то трогать. Но ты приходишь к зубному и разрешаешь ему доступ к зубам. При этом бац!!! Он может вполне что-то сделать с твоими кишками. Это как? Норм?


M>>Хирург иногда делает что-то подобное


H>Ты не понял мою мысль про зубного? Ну ок.


Ты не понял мою мысль про хирурга
Маньяк Робокряк колесит по городу
Re: friend
От: rg45 СССР  
Дата: 15.11.25 16:15
Оценка: +1
Здравствуйте, Hоmunculus, Вы писали:

H>Как считаете — friend это костыль для кривой архитектуры или норм?


Само по себе нет, зависит от ситуации. В качестве классического примера можно привести определённые пользователем операторы ввода/вывода. Можно конечно, определять в классах функции-члены типа read/write, save/load и т.п и через них определять операторы, но зачем же плодить лишние сущности.

А вот когда на этапе проектирования что-то провтыкали, а потом начинают латать эти косяки добавлением друзей, вот это уже костыли.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 15.11.2025 16:16 rg45 . Предыдущая версия .
Re: friend
От: Went  
Дата: 17.11.25 08:14
Оценка:
Здравствуйте, Hоmunculus.
Давно подумаю над тем, что зону действия friend-деклараций стоило ограничить одной private-protected секцией. Чтобы можно было явно указать что именно и кому ты открываешь.
Re: friend
От: Maniacal Россия  
Дата: 17.11.25 08:49
Оценка:
Здравствуйте, Hоmunculus, Вы писали:

H>Как считаете — friend это костыль для кривой архитектуры или норм?


Это очень полезный костыль, если поверх существующего кода резко понадобилось добавить, например, сбор статистики или мониторинг валидности состояния объектов не затрагивая имеющийся отлаженный код и его поведение.
Re[2]: friend
От: rg45 СССР  
Дата: 17.11.25 08:54
Оценка:
Здравствуйте, Went, Вы писали:

W>Давно подумаю над тем, что зону действия friend-деклараций стоило ограничить одной private-protected секцией. Чтобы можно было явно указать что именно и кому ты открываешь.


Не думаю, что это хорошая идея. По-моему, это будет способствовать как раз той самой нездоровой дружественности при которой возникают избыточные и зацикленные зависимости между классами. Одно дело наделить дружественностью функцию/оператор, которая является неотъемлемой частью контракта класса и объявлена в одном с классом заголовке. И совсем другое дело — плести замысловатые кружева зависимостей между классами.
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: friend
От: Went  
Дата: 17.11.25 09:53
Оценка:
Здравствуйте, rg45, Вы писали:

R>Не думаю, что это хорошая идея. По-моему, это будет способствовать как раз той самой нездоровой дружественности при которой возникают избыточные и зацикленные зависимости между классами. Одно дело наделить дружественностью функцию/оператор, которая является неотъемлемой частью контракта класса и объявлена в одном с классом заголовке. И совсем другое дело — плести замысловатые кружева зависимостей между классами.

Тут не поспоришь. Но, можно рассуждать, что дружественность бывает двух видов: первая, это "дружественность единой сущности", про которую ты написал выше, вторая — "дружественность единой системы". Это когда создаётся некоторая система объектов, и мы хотим открыть пользователю только некоторый интерфейс. Ну, самое простое — у нас есть какая-то "божественная базовая сущность", а она обслуживается разными сервисами. Ну, совсем примитивно — базовый контрол, который может быть рисуем, управляем, наводим мышкой и т.п. Все эти и сервисы, и функции божественного предка, которыми они оперируют, пользователю не нужны. Ну, чтобы он, например, не додумался вызывать контролу "нарисуйся" вручную. И очень хочется сказать "вот у нас набор приватных функций рисования, открытых только для рисователя", например. В C# есть для этого (приблизительно) модификатор internal. Я не хочу сейчас разводить дискуссию о чистоте и идеологической трушности такого подхода, понятно, можно как-то обойтись, заменить на защищенные интерфейсы или композицию объектов. Но вот так просто, без изысков это было бы удобно, мне кажется.
Re: friend
От: sergii.p  
Дата: 17.11.25 10:13
Оценка: :)
Здравствуйте, Hоmunculus, Вы писали:

H>Как считаете — friend это костыль для кривой архитектуры или норм?


friend для лохов, нормальные пацаны используют public.
Вообще не видел когда применяли криво. Для реализаций оператора сравнения и std::hash использование более чем оправдано.
Случаи, когда из одного класса нужно получить потроха другого можно назвать костылём, но как выше уже сказал, нормальные пацанчики обходят это обычным public. Если кто-то написал friend, уже повод задуматься о личности написавшего и его внутреннем мире. Может он маньяк и обзывать его код костылём себе дороже.
Re[2]: friend
От: rg45 СССР  
Дата: 17.11.25 11:19
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>friend для лохов, нормальные пацаны используют public.


И тут должна быть такая картинка:

Пацаны ООП не юзают

--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 17.11.2025 11:33 rg45 . Предыдущая версия .
Re: friend
От: MNZ Россия  
Дата: 18.11.25 08:52
Оценка: 11 (3)
Здравствуйте, Hоmunculus, Вы писали:

H>Как считаете — friend это костыль для кривой архитектуры или норм?


В прямых руках норм. В конце-концов, при помощи friend можно не только наивно открыть доступ ко всем своим потрохам. Например, для friend придумали что-то вроде инверсии зависимости в виде паттерна Passkey, при помощи которого можно разрешать вызывать одну конкретную функцию классам из белого списка. Что-то вроде:
class Me {
public:
    struct Passkey {
        friend class Class1;
        friend class Class2;
    private:
        Passkey() = default; // Доступен только друзьям
    };

    void SomeFunc(Passkey);
};

class Class1 {
public:
    void CallMe() {
        Me me;
        me.SomeFunc(Me::Passkey{});
    }
};
Re[3]: friend
От: B0FEE664  
Дата: 18.11.25 14:35
Оценка: 4 (1)
Здравствуйте, Hоmunculus, Вы писали:

H>Ну смотри. Есть какое-то приватное поле. Никто не должен ничего о нем знать. Вот никто. Это суть этого поля. Оно просто как-то там работает. А тут класс говорит — вот это мой друг. Все. Друг может ВСЕ!!! Это правильно?


Инкапсуляция — это не нечто самоценное само по себе. Инкапсуляция — это механизм для упрощения программирования, когда одна часть кода изолируется от другой, исключая тем самым необдуманное влияние одного кода на другой. Второй аспект инкапсуляции — это возможность переиспользовать один и тот же класс в различных независимых частях кода, в какой-то степени обеспечивая его универсальность. Если мы объявляем другом класса некий элемент, то получаем два следствия: мы усложняем код увеличивая его связность и уменьшаем универсальность. Чтобы оценить оправданность добавления друга надо посмотреть на объём кода, который придётся написать, чтобы сделать тоже самое без объявления дружбы. Может оказаться, что трудозатраты на работу без дружбы столь значительны, что не имеют смысла. Однако, также следует иметь ввиду, что тут есть классическая дилемма: выиграв на короткой дистанции можно проиграть на длинной и наоборот. Понятно, что для простых проектов (которые могут быть разработаны и написаны одним человеком) в дружбе нет особой опасности. Если же речь идёт о проекте рассчитанным на десятилетия и десятки сменяющихся программистов, то излишняя дружба ведёт к проблемам.

Думаю, что здесь следует заметить, что, в отличии от вышеприведённого случая, дружба может использоваться для ограничения доступа и увеличению инкапсуляции.
Ниже я попытался проиллюстрировать, как это может быть.
// the data that can be created only by TOwner class
//
template<class TOwner, class TData>
class PrivateData
{
    private:
        friend TOwner;
        using value_type = TData;
    private:
        PrivateData(const value_type& constData)
          : m_data{constData}
        {
        }
    public:
        bool operator == (const PrivateData& constData) const
        {
            return m_data == constData.m_data;
        }

        bool operator != (const PrivateData& constData) const
        {
            return m_data != constData.m_data;
        }
    private:
        value_type m_data{};
};


class RedAndWhite
{
    public:
        using value_type = PrivateData<RedAndWhite, const char*>;
    public:
        inline static const value_type c_red   = "red"  ;
        inline static const value_type c_white = "white";
    public:
        RedAndWhite(const value_type& state)
            : m_state{state}
        {
        }

        const value_type& get() const noexcept
        {
            return m_state;
        }
        ...
    private:
        value_type m_state;
};


inline bool operator == (const RedAndWhite& lhs, const RedAndWhite& rhs)
{
    return lhs.get() == rhs.get();
}


Здесь RedAndWhite — это такое перечисление (enum) из строк, константные значения которых никто из вне класса RedAndWhite создать не сможет.
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.