Это уместное использование классовой дружбы? - PullRequest
4 голосов
/ 25 января 2011

При создании родительских и дочерних диалоговых классов Windows, как правило, рекомендуется сделать дочерний класс другом родительского класса для доступа к его личным данным или использовать функции доступа?

Ответы [ 3 ]

3 голосов
/ 25 января 2011

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

Единственное, что мне было нужно, это переписать рендерер на основе openGL в ActiveX - когда мне нужно было получить много данных модели низкого уровня, но я не мог (по нетехническим причинам) переопределить обычную ABC.

2 голосов
/ 25 января 2011

Недавно у меня была похожая ситуация, когда я хотел представить несколько закрытых переменных-членов класса A для класса B.

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

Я не хотел делать B другом A, потому что это выставило бы всех частных членов A к B.

Итак, я создал другой класс (частный интерфейс A-to-B) исключительно для этой цели. Это друг A, и у него нет ничего, кроме функций доступа:

class A
{
    int top_secret; // only A has access to it
    int secret; // only A and B have access to it
    friend struct AToBInterface;
};

struct AToBInterface
{
    static int secret(const A& object) {return object.secret;}
};

class B
{
    void DoSecretStuff(A& object)
    {
        int secret = AToBInterface::secret(object);
        ...
    }
};

Вы можете настроить синтаксис (например, если вам нужен доступ для чтения и записи), это всего лишь идея. Я использую его только в одном месте кода, так что нет проблем, если синтаксис немного сложный.

0 голосов
/ 25 января 2011

ИМХО, почти никогда.

«Друг» часто используется для нарушения инкапсуляции в том смысле, что он может позволить внешнему объекту получить доступ к частным данным вашего класса. Вы почти никогда не хотите этого делать - часто лучше / безопаснее предоставлять «полуприватные» данные через общедоступные средства доступа (которые могут проверять достоверность), чем предоставлять конфиденциальную информацию другому классу (который может взломать все вокруг вас).

Однако иногда у вас будет пара / группа очень тесно связанных классов, в которых имеет смысл хранить их как отдельные классы, но им нужен низкоуровневый доступ к данным, которые на самом деле не должны передаваться всему миру. Здесь можно использовать «друга» - с осторожностью.

Обычно старайтесь ограничить область действия друзей (например, методы друзей, а не классы друзей), чтобы минимизировать области, в которых разрешен прямой доступ к частным данным. Сохраняйте это как можно более простым - помните, что другой программист, читающий ваш код, может подумать, что «частные» означают, что данные действительно являются частными, и их могут споткнуть друзья. Кроме того, чем больше друзей вы используете, тем более тесными и сложными в поддержании будет ваш дизайн. Они могут быть полезны, но убедитесь, что у вас есть хорошее обоснование для каждого использования.

...