2013-08-28 19 views
9

Ho una classe esterna A. Ha un metodo A::fun. In questo metodo, ha una classe locale o interna B. La mia domanda è: B è un amico di A?È una classe locale in un metodo di una classe un amico di questa classe?

Penso che non lo sia. È giusto? Se è così, penso che la classe B un amico di A sia molto utile poiché B può accedere ai membri privati ​​e protetti di A. Inoltre, poiché B è locale in un metodo, non è accessibile ad altri e quindi sicuro come amico di A. Come ovviare a lasciare che B l'accesso agli membri privati ​​e protetti di A?

+4

Se non si dice esplicitamente di essere amici, allora non sono amici. – andre

+1

@andre E non penso che ci sia un modo sintattico per renderli amici. – Angew

risposta

14

No, non sono amici.

Ma le classi locali hanno lo stesso accesso ai nomi al di fuori della funzione come funzione stessa.

Lo standard dice:

9.8 dichiarazioni di classe locali [class.local]

Una classe può essere dichiarata all'interno di una definizione di funzione; tale classe è chiamata classe locale. Il nome di una classe locale è locale rispetto al suo ambito di chiusura. La classe locale è nell'ambito dell'ambito di inclusione e ha lo stesso accesso ai nomi al di fuori della funzione come fa la funzione di inclusione. Le dichiarazioni in una classe locale non devono utilizzare odr (3.2) una variabile con durata di archiviazione automatica da un ambito chiuso.

La grande differenza di prendere nella conta è che il vostro classe locale sarà accessibile solo all'interno della funzione.

Ma dopo che:

  • Un amico di una classe è una funzione o di classe che viene dato il permesso di usare i nomi dei membri privati ​​e protetti dalla classe.
  • La classe locale è nell'ambito dell'ambito di inclusione e ha lo stesso accesso ai nomi esterni alla funzione come la funzione di inclusione. Cioè, può accedere ai membri protetti e privati ​​della classe a cui appartiene la funzione.
6

No, non sono amici. Ma importa?
Non proprio! considerare questi fatti:

  1. All'interno della funzione membro avrete sempre accesso ai membri della classe a cui appartiene la funzione.
  2. Non è possibile accedere alla classe locale da nessuna parte oltre la funzione.

Quindi non importa se sono amici o no. Farai sempre riferimento ai membri della classe esterna all'interno della sua funzione membro.

Online Sample:

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

int main() 
{ 
    return 0; 
} 
+0

Sarà apprezzato un ragionamento tecnico per il downvote. –

+1

Non ho votato, ma la mia interpretazione dell'amicizia nella domanda è nella direzione opposta: può 'B' vedere i membri non pubblici di' A'? – juanchopanza

+0

@juanchopanza: non ha importanza perché il nome della classe locale è locale per l'ambito che lo include, non è possibile utilizzare questo nome oltre l'ambito locale e l'ambito locale è nella funzione membro, quindi è sempre possibile accedere ai membri della classe esterna. –

3

Questo compila in Clang:

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

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

La classe interna ha accesso ai membri privati ​​di A, ma non perché è un amico, ma perché è considerato un membro. Poiché i membri di una classe hanno accesso a membri privati, questo include classi interne e classi locali di funzioni membro.

Vedere [class.access] p2.

+1

+1 per spiegare che non è un amico ma _still_ ha accesso ai membri privati. – Andy

Problemi correlati