Является ли локальный класс в методе класса другом этого класса?

У меня есть внешний класс A. У него есть метод A::fun. В этом методе он имеет локальный или внутренний класс B. Мой вопрос: B друг A?

Я думаю, что это не так. Это правильно? Если это так, то я думаю, что класс B, друг A, очень полезен, поскольку B может получить доступ к закрытым и защищенным членам A. И более того, поскольку B является локальным в методах, он недоступен для других и, следовательно, безопасен как друг A. Как разрешить B доступ к закрытым и защищенным членам A?


person user1899020    schedule 28.08.2013    source источник
comment
Если вы прямо не говорите, что они друзья, значит, они не друзья.   -  person andre    schedule 28.08.2013
comment
@andre И я не думаю, что есть синтаксический способ подружить их.   -  person Angew is no longer proud of SO    schedule 28.08.2013


Ответы (3)


Нет, они не друзья.

Но локальные классы имеют такой же доступ к именам вне функции, как и сама функция.

Стандарт говорит:

9.8 Объявления локальных классов [class.local]

Класс может быть объявлен в определении функции; такой класс называется локальным классом. Имя локального класса является локальным по отношению к окружающей его области. Локальный класс находится в области действия объемлющей области и имеет такой же доступ к именам вне функции, как и объемлющая функция. Объявления в локальном классе не должны использовать (3.2) переменную odr с автоматическим сроком хранения из объемлющей области.

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

Но после этого:

  • Друг класса — это функция или класс, которым разрешено использовать частные и защищенные имена членов класса.
  • Локальный класс находится в области действия объемлющей области и имеет такой же доступ к именам вне функции, как и закрывающая функция. То есть он может получить доступ к защищенным и закрытым членам класса, к которому принадлежит функция.
person Pierre Fourgeaud    schedule 28.08.2013

Нет, они не друзья. Но имеет ли это значение?
Не совсем так! рассмотреть эти факты:

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

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

Образец в Интернете:

class A
{
    int i;
    void doSomething()
    {
        class B{public: int ii;};
        B obj;
        obj.ii = i;
    }
};

int main()
{
    return 0;
}
person Alok Save    schedule 28.08.2013
comment
Я не голосовал против, но моя интерпретация дружбы в вопросе в другом направлении: может ли B видеть непубличных участников A? - person juanchopanza; 28.08.2013
comment
@juanchopanza: вряд ли имеет значение, потому что имя локального класса является локальным для окружающей области. Нельзя использовать это имя за пределами локальной области, а локальная область находится в функции-члене, поэтому всегда есть доступ к членам внешнего класса. - person Alok Save; 28.08.2013
comment
@juanchopanza дружба это дружба, возможность видеть закрытых участников - это возможность видеть закрытых участников - person triclosan; 28.08.2013

Это компилируется в Clang:

class A {
  typedef int Int;
  void fn();
};

void A::fn() {
  class B {
    Int i;
  };
}

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

См. [class.access] стр. 2.

person Sebastian Redl    schedule 28.08.2013
comment
+1 за объяснение, что это не друг, но до сих пор имеет доступ к закрытым членам. - person Andy; 28.08.2013