Ограничение доступа к методам класса

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

Я проверил

Могу ли я получить доступ к закрытым членам из-за пределов класс без друзей?

С++: Есть ли способ ограничить доступ к определенным методам определенным классам, не открывая доступ к другим закрытым членам?

класс друзей с ограниченным доступом

Но все (на самом деле не все) требуют изменения кода клиента. Код клиента не должен меняться.

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


person a_secenthusiast    schedule 21.01.2012    source источник


Ответы (2)


Классы в C++ сделаны friends, чтобы указать на особую преднамеренную сильную связь между классами. Такое использование friend на самом деле улучшает инкапсуляцию, а не ломает ее, как это, возможно, популярное мнение.
Как?
Без дружбы единственным нехитрым способом предоставить функциональность другому классу было бы предоставление public, get и set члена. функций, это фактически нарушает инкапсуляцию, потому что все классы (даже те, которым это не нужно) теперь имеют доступ к этим методам и, следовательно, члены увеличивают риск потенциальной поломки данных класса.

Вернемся к вашей ситуации. Если у вас есть 100 классов, которым нужен доступ к этому конкретному классу, значит, у вас уже есть правильный дизайн, если эти методы указаны как public. Теперь попытка сделать эти методы private для будущих классов - это попытка взломать ваш существующий дизайн, ваш дизайн его не поддерживает.

Создание существующих классов как friends не идеально соответствует вышеупомянутым критериям и, следовательно, не является хорошим выбором для сценария.
Однако, учитывая ситуацию, нет другого способа реализовать это. Сделать существующие классы friend и предоставить им специальный доступ кажется единственным выходом. Это все еще плохо, потому что 100 классов, которые имели доступ только к нескольким методам, теперь будут иметь доступ ко всему вашему классу.

person Alok Save    schedule 21.01.2012
comment
Он может объявить в качестве друзей только некоторые методы, а не весь класс. - person Idov; 21.01.2012
comment
@Idov: О да, если только определенные методы внутри этих 100 классов нуждаются в доступе, тогда это возможно, OP, безусловно, может это сделать. В этом случае последний пункт, который я сказал, не применяется. Однако я не уверен, какова точная ситуация, я процитировал наихудший сценарий. - person Alok Save; 21.01.2012
comment
@Idov: Большое спасибо. Если я вас правильно понял, вызывающие методы (разных классов) должны быть объявлены как друзья. Я попробовал это в тестовой программе, и это сработало. Большое Вам спасибо. Можно ли объявить несколько методов в классе (в данном случае это A) как дружеские и при этом частные, чтобы методы дружественного класса имели доступ только к ним, кроме общедоступных интерфейсов? - person a_secenthusiast; 24.01.2012
comment
@ user917279: Да, метод может быть объявлен как private в своем собственном классе и может быть объявлен как friend другого класса. - person Alok Save; 24.01.2012

Думаю можно извлечь интерфейс класса A (пусть будет IA) и сделать A для реализации IA. Вы вообще не должны определять эти публичные методы в IA.

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

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

Кроме того, вы получаете небольшие накладные расходы из-за virtual функций.

person Lol4t0    schedule 21.01.2012