Я думал, что смогу сделать это:
class TestA
{
private:
class Nested
{
};
};
class TestB
{
public:
friend class TestA;
friend class TestA::Nested;
};
Но я получаю сообщение об ошибке:
Error C2248 'TestA::Nested': cannot access private class declared in class
Есть ли способ подружиться с частным вложенным классом? Как мне это сделать?
Я столкнулся с этой ошибкой при попытке скомпилировать проект MSVC 6 в MSVC 2017 (C++17). Думаю, тогда это сработало.
TestA необходимо объявить TestB как friend. TestB не может использовать TestA::Nested, если TestA не позволяет это.
TestA тоже должен быть другом или только чтоNested?





Вы пытаетесь использовать private вложенный класс TestA в TestB, тогда вы должны объявить TestB как friend в TestA. например
class TestA
{
private:
class Nested
{
};
friend class TestB; // allow TestB to access the private members of TestA
};
Точно так же вы получаете доступ к любой другой частной вещи. Вам нужна дружба по-другому:
class TestA
{
friend class TestB; // <== this
private:
class Nested
{
};
};
class TestB
{
public:
friend class TestA;
friend class TestA::Nested; // <== now we're a friend of TestA, so we can access it
};
@Quentin Я говорю, что Барри нашел structуральный образ жизни while, поддерживая class. Вот почему я стремлюсь быть friend.
@SombreroChicken И вы не можете произнести поддержание без int main().
Это сделает это:
class TestA {
friend class TestB;
private:
class Nested {};
};
class TestB {
public:
friend class TestA::Nested;
};
Объяснение: TestA сам несет ответственность за предоставление доступа к своим внутренностям другим. Представьте себе, что любой class может навязчиво использовать дружбу, чтобы получить доступ к внутренностям других классов (из библиотек и т. д.), это открыло бы дверь для произвольного нарушения инкапсуляции.
@Bathsheba Спасибо, что придали моему ответу больше уверенности в себе;)
Как дружба предоставление с недоступным классом нарушит инкапсуляцию? Более вероятной проблемой может быть хрупкость от переименования/удаления частного класса.
@DavisHerring Переименование / удаление - действительно еще одна проблема, хороший момент. Я имел в виду, что если какой-то клиентский код может установить отношения friend с другим классом, возможно, за пределами его собственной кодовой базы, то это нарушает инкапсуляцию.
Просто закомментируйте строку friend class TestA::Nested;, как показано ниже:
class TestA
{
private:
class Nested
{
};
};
class TestB
{
public:
friend class TestA;
// friend class TestA::Nested;
};
Поскольку TestA::Nested имеет ту же область действия, что и TestA, метод TestA::Nested может получить доступ к закрытым/защищенным членам TestB.
Интересно, протестировали ли даунвотеры это на самом деле. Этот ответ правильный на 100% godbolt.org/z/VypZo2
@sebrockm - Вы пропустили тот факт, что он не позволяет получить доступ Nested? Это не отвечает на вопрос правильно. Или вы голосуете за каждый фрагмент кода независимо от его актуальности?
@StoryTeller, пожалуйста, помогите мне определить часть вопроса, которая хочет получить доступ Nested. Если мой английский не слишком испорчен, ОП хочет предоставить TestA::Nested доступ к приватным полям TestB (он же сделать Nested другом TestB). И этот ответ говорит: «Если вы подружитесь с TestA, Nested тоже автоматически станет другом». Так что же не так с этим ответом?
@sebrockm - Nested тоже не друг, он использует дружбу TestA и правила области видимости. Что может быть или не быть приемлемым. Однако это не отвечает на вопрос, как подружиться с Nested самой собой. ОП, кажется, хочет, чтобы несмотря подружился TestA. Следовательно, люди имеют право считать этот ответ бесполезным для вопроса. 100% правильно или нет.
@StoryTeller, может быть предметом обсуждения вопрос о том, трепетно ли относится к некоторым именам (называется ли это дружбой или нет), хотя он делает то же самое, оправдывает отрицательный голос или нет. Однако я скорее верю, что даунвотеры просто не поверили, что это работает, не проверив это, или неверно истолковал, кто должен иметь доступ к кому (как это только что случилось с вами).
@sebrockm - Не лезь мне в рот. Я назвал это неуместным, а не неправильным. И не претендуйте на то, чтобы знать, как другие голосуют или на основании чего. Ваш голос в порядке, ваш комментарий - нет. Добрый день.
@TarickWelling Нет.
TestBне происходит отTestA.