класс друга: унаследованные классы тоже не друзья? - PullRequest
4 голосов
/ 29 января 2009

В C ++ у меня есть класс A, который дружит с классом B.

Похоже, унаследованные классы B не являются друзьями класса A.

Это ограничение C ++ или моя ошибка?

Вот пример. При компиляции я получаю сообщение об ошибке "return new Memento":

Memento :: Memento: невозможно получить доступ к приватному участнику, объявленному в Memento.

class Originator;

class Memento
{
  friend class Originator;

  Memento() {};

  int m_Data;

public:
  ~Memento() {};
};

class Originator
{
public:
  virtual Memento* createMemento() = 0;
};

class FooOriginator : public Originator
{
public:
  Memento* createMemento()
  {
    return new Memento; // Impossible to access private member of Memento
  }
};

void main()
{
  FooOriginator MyOriginator;
  MyOriginator.createMemento();

}

Конечно, я мог бы добавить FooOriginator в качестве друга Memento, но тогда это означает, что мне придется добавить все классы, унаследованные от Originator, в качестве друга Memento, чего я бы хотел избежать.

Есть идеи?

Ответы [ 5 ]

7 голосов
/ 29 января 2009

См .: Область друзей в C ++
Проголосовал точный дубликат.

I looks like inherited classes of B are not friend of class A.

Корректное

I this a limitation of C++ or my mistake ?

Так работает C ++. Я не рассматриваю это как ограничение.

6 голосов
/ 29 января 2009

Дружба не передается по наследству, вы должны явно объявить все дружеские отношения. (См. Также « дружба не является наследственной, переходной или взаимной »)

3 голосов
/ 29 января 2009

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

0 голосов
/ 29 января 2009

Дружба не наследуется, см. http://www.cplusplus.com/doc/tutorial/inheritance.html, Что наследуется от базового класса?

0 голосов
/ 29 января 2009

Директива friend изначально была задумана как «лазейка» для обхода механизма инкапсуляции.

С другом вы должны точно указать (!), Какие классы являются вашими друзьями. Дружба не наследуется, поэтому FooOriginator не имеет доступа к Memento в вашем примере.

Но в идеале, прежде чем подумать, как решить свою проблему с помощью директивы friend , я бы посоветовал взглянуть на ваш дизайн в целом и попытаться избавиться от необходимости использовать друг как можно видеть, он живет в той же категории, что и наши любимые goto :)

...