Альтернатива дружбе? - PullRequest
       33

Альтернатива дружбе?

1 голос
/ 28 октября 2011

Есть ли альтернатива дружбе в следующем сценарии?

У меня есть класс Window, который представляет окно пользовательского интерфейса.Кроме того, класс WindowManager, реализованный как одноэлементный, управляет всеми объектами окна в моем приложении (отображает пользовательский интерфейс, отправляет события и т. Д.)метод и функции одиночного экземпляра для визуализации пользовательского интерфейса и отправки события пользовательского интерфейса.

Я также хотел бы, чтобы объекты Window регистрировались в WindowManager во время создания и отменялись при уничтожении.Методы WindowManager::register и WindowManager::deregister будут либо частными, либо защищенными, потому что я не хочу, чтобы клиенты (кроме Window объектов) могли использовать этот интерфейс.

Есть ли способ избежать дружбымежду Window и WindowManager в этом случае?Возможно, совершенно другой способ достижения подобных результатов?

Ответы [ 5 ]

4 голосов
/ 28 октября 2011

Да, но дружба - лучшее решение, поскольку оно разработано для этого сценария.

Другой способ - сделать Window членом WindowManager (обратите внимание, для этого требуется новый C ++ 11правила доступности).Или это происходит от члена WindowManager.Или он может быть производным от WindowManager.

Вы также можете поместить закрытый тип в Window, создать тип ключа, вложенный в Window, который может быть создан только из этого закрытого типа и требующий передачиэкземпляр этого типа ключа к WindowManager.Это должно работать в компиляторах до C ++ 11.

Конечно, любой подход можно обойти, используя достаточное количество приведений.

2 голосов
/ 28 октября 2011

Другое решение (лучше не обязательно:]) - установить регистрацию окна на a separate component - скажем, WindowRegister. WindowRegister может иметь открытый интерфейс для регистрации, а также может быть частным членом WindowManager.

problem with friendship is that it is not inherited (друг моего дедушки не нужен, мой друг) - и есть большая вероятность, что Window или WindowManger будут полиморфными.

Привет

2 голосов
/ 28 октября 2011

Использовать вложенные классы.

WindowManager {
  private:
    static void construct();
    static void destruct();
  public:
    class InternalWindow { // can access WindowManager's private members (no scoping needed)
      InternalWindow() { construct(); }
      ~InternalWindow() { desstruct(); }
    };
};

typedef WindowManager::InternalWindow Window; // to make scoping easier
2 голосов
/ 28 октября 2011

Использование Friend корабля кажется здесь уместным. Вы хотите указать Преднамеренную сильную связь между двумя классами, что удачно указано через друзей.

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

Эмпирическое правило: публичный слишком слабый, а приватный слишком сильный, вам нужна некоторая форма выбранного доступа: либо защищенный, либо дружественный.

Использование Friend ship - лучшее решение здесь.

1 голос
/ 28 октября 2011

Есть несколько других вариантов. Например:

  • Вы можете использовать математику указателя, код сборки и знания о расположении классов в памяти для вызова закрытых методов во время выполнения. Это, однако, не очень переносимо.
  • Вы можете сделать метод общедоступным, но потребовать, чтобы он принимал параметр, криптографически подписанный закрытым ключом, который находится в классе Window, что не позволяет другим классам фактически вызывать метод и заставлять его делать что угодно.
  • Вы можете сделать метод защищенным и наследовать одно от другого.
  • Вы можете создать общий суперкласс, от которого они оба наследуют, и использовать защищенные методы для связи между ними.
  • Вы могли бы использовать мало используемое ключевое слово "враг", чтобы позволить им запускать закрытые методы друг друга, но только когда у них есть материал шантажа, который уличает другой класс. (Хорошо, это не настоящая языковая функция, но она должна быть.)

Или вы могли бы просто сделать их друзьями. Это намного проще и разумнее, чем любой другой вариант, и почему существуют друзья.

...