Видит ли друг базовые классы? - PullRequest
6 голосов
/ 26 марта 2012

Приведенный пример кода:

class Base {
public:
  bool pub;
protected:
  bool prot;
};

class Derived : private Base {
  friend class MyFriend;
};

class MyFriend {
  Derived _derived;

  void test() {
    // Does standard provide me access to _derived.pub and _derived.prot?
    cout << "Am I allowed access to this: " << _derived.pub
         << " and this: " << _derived.prot;
  }
};

Дает ли мне возможность быть другом, если бы я был другом, как если бы я был членом-членом класса, которому я являюсь другом? Другими словами, могу ли я получить доступ к защищенным и общедоступным членам базового класса, унаследованным в частном порядке, поскольку я являюсь другом?

Ответы [ 3 ]

7 голосов
/ 27 марта 2012

Объединение ответов Давида Родригеса - Дрибея и Лучиана Григоре:

Да, пример в вопросе работает, однако, как указывает Дэвид, защищенные члены не доступны напрямую через базовый класс. Вы получаете доступ к защищенным членам только при доступе через Derived, у вас нет доступа к тем же участникам при доступе через Base.

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

Вот пример, который проясняет разницу:

class MyFriend {
  Derived _derived;

  void test() {
    bool thisWorks = _derived.pub;
    bool thisAlsoWorks = _derived.prot;

    Base &castToBase = _derived;

    bool onlyPublicAccessNow = castToBase.pub;
    // Compiler error on next expression only.
    // test.cpp:13: error: `bool Base::prot' is protected
    bool noAccessToProtected = castToBase.prot;
  }
};
2 голосов
/ 26 марта 2012

Объявление друга создаст MyFriend доступ к наследственному отношению (то есть private для остального мира), но не предоставит ему доступ к защищенным членам базы, только к общедоступному интерфейсу.

void MyFriend::test() {
   Derived d;
   Base & b = d;          // Allowed, MyFriend has access to the relationship
   b.prot = false;        // Not allowed, it does not have access to the base
}
1 голос
/ 26 марта 2012

Да, потому что Base члены также являются Derived членами (поскольку они не private в Base).

...