Доступ к внешнему классу C++ доступ к внутреннему классу private-почему запрещено

Привет мне интересно, почему стандарт C++ позволяет нам во вложенных классах получать доступ к закрытым полям внешнего класса, в то время как он запрещает доступ к закрытым полям внутреннего класса из внешнего класса. Я понимаю, что это пример:

class OuterClass{
public:
    class InnerClass{
    public:
        void printOuterClass(OuterClass& outer) {cout << outer.m_dataToDisplay;};
    };
private:
    int m_dataToDisplay;
};

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

class Algorithm{
public:
    class AlgorithmResults{
    public:
        void readAlgorithmResult();
    private:
        void writeAlgorithmResult();
    };

    void calculate(AlgorithmResults& results, Arguments...){
       //calculate stuff
       results.writeAlgorithmResult(results);
    }
};

для меня эта структура имеет смысл, хотя это не разрешено в C++. Я также заметил, что некоторое время оба были разрешены на Java, но теперь второй пример также запрещен. В чем причина, что первый пример разрешен, а другой отрицается?

3 ответов


по сути, внутри имена областей, объявленные ранее в этой области, действительны и могут использоваться напрямую (если они не затенены). Код за пределами область не может напрямую использовать имена, объявленные внутри области. Например. код после блока фигурных скобок не может напрямую использовать переменные, объявленные внутри этого блока (пример косвенного использования-когда внешний код имеет доступ к указателю на статическую переменную внутри блока фигурных скобок).


для второй пример, просто сделайте Algorithm a friend of AlgorithmResults:

class AlgorithmResults
{
    friend class Algorithm;

вложенные классы могут получить доступ к частным полям внешнего класса, потому что он является членом внешнего класса, так же, как и другие члены.

из 11.7 / 1 вложенных классов [class.доступ.nest]

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

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

члены заключительный класс не имеет специального доступа к членам вложенного класса; обычные правила доступа (пункт 11) будет исполнено.


встречный вопрос: почему вы хотите разрешить это?

Если вам нужен внешний класс, у вас есть доступ к внутренним внутренним частям внутреннего класса, вы можете подружиться:

    class Foo {
    public:
            class Frob {
                    friend class Foo;
                    int privateDataMember;
            };

            Foo () {
                    Frob frob;
                    frob.privateDataMember = 3735928559;
            }
    };

C++ не имеет устройства для unfriend, поэтому разрешение частного доступа по умолчанию к внешнему классу украло бы у вас инструмент проектирования класса и дало бы уменьшенную инкапсуляцию по умолчанию.