2016-03-15 22 views
9

Ciao mi chiedo perché lo standard C++ ci consente nelle classi nidificate di accedere ai campi privati ​​della classe esterna, mentre vieta di accedere ai campi privati ​​della classe interna dalla classe esterna. Capisco, questo esempio:C++ Accesso alla classe esterna Privato della classe interna - perché vietato

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

va bene, perché cosa, a volte la classe interna può essere complicata. Ma penso seguente scenario è anche bene:

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

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

Per me tale struttura ha perfettamente senso, anche se non è consentito in C++. Ho anche notato che per un po 'di tempo entrambi erano permessi in Java, ma ora anche il secondo esempio è proibito. Qual è il motivo, il primo esempio è consentito e un altro è negato?

risposta

15

In sostanza, il codice all'interno di un ambito ha accesso alle cose dichiarate in precedenza in tale ambito (a meno che non siano ombreggiate). Codice all'esterno di un ambito non ha accesso alle cose all'interno dell'ambito. Per esempio. codice dopo un blocco di parentesi graffe, non ha accesso alle variabili dichiarate all'interno di quel blocco.


Per il secondo esempio, basta fare Algorithm un friend di AlgorithmResults:

class AlgorithmResults 
{ 
    friend class Algorithm; 
+5

Scusate, ho invertito l'amicizia e ho dovuto risolvere. Questa è un'altra prova del fatto che il caffè è necessario prima di postare in SO! –

4

Le classi nidificate potevano accedere ai campi privati ​​della classe esterna, perché è un membro della classe esterna, proprio uguale al altri membri.

Da 11.7/1 classi nidificate [class.access.nest]

Una classe annidata è un membro e come tale ha gli stessi diritti di accesso di tutti gli altri membri.

D'altra parte, la classe esterna non ha diritti di accesso speciali sulla classe nidificata, sono solo normali relazioni.

I membri di una classe di chiusura non hanno accesso speciale ai membri di una classe nidificata; le normali regole di accesso (Clausola 11) devono essere rispettate.

+0

Questo semplicemente ripete i fatti, ma l'OP vuole giustificare i fatti (anche se non penso che sia una domanda particolarmente valida). –

+0

@BarryTheHatchet Ho cercato di spiegarlo dai diversi punti di vista della classe interiore alla classe esterna, e dalla classe alla classe interiore. Non chiaro? – songyuanyao

+0

Hai spiegato le regole molto bene.Non penso che sia quello che l'OP stava chiedendo. –

5

Domanda contraria: perché vuoi accettarlo?

Se avete bisogno di un classe esterna avere accesso a una classe interna interni privati, è possibile fare amicizia:

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

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

C++ non ha alcun dispositivo per Unfriend, permettendo così di default l'accesso privato ad una classe esterna ruberebbe voi uno strumento di progettazione di classe e riduce l'incapsulamento di default.

Problemi correlati