Relazione di classe interna ed esterna: la classe esterna dovrebbe essere amica di quella interiore?

1

Questo design è cattivo?

Rompe l'incapsulamento? La struttura class B è un componente di class A . Pertanto, class A ha bisogno di accedere ai membri di class B . Lascia che una casa sia class A . Lascia che una governante sia un componente di class A . Lascia che una stanza sia class B . Una stanza, e quindi class B , è un componente di class A .

Un governante ha bisogno di accedere ai membri di room per cambiare bedroom_dirty = true in bedroom_dirty = false , per esempio. Una governante non appartiene a room (cioè class B ); quello sarebbe un roomkeeper, e non stiamo parlando di quello.

Questo design è sbagliato?

class A
{
  class B
  { 
    friend class A{}; // A has access to all of B's members
  };
};
    
posta Jossie Calderon 26.06.2016 - 22:17
fonte

1 risposta

3

Perché classi annidate?

Bjarne Stroustrup spiega in " La progettazione e l'evoluzione di C ++ ", l'origine e la logica dietro le classi annidate:

  • C ++ originale nel 1984 aveva un singolo spazio per i nomi (pagine 5 e 102).
  • l'uso di classi nidificate era un compromesso tra il concetto di una classe come ambito e la necessità di compatibilità con C (pagina 102)
  • era inoltre desiderato promuovere il principio di località, cioè pezzi di codice riutilizzabili autonomi. Le classi annidate sembrano contribuire a questo obiettivo (pagina 118)
  • I namespace come li conosciamo oggi sono stati aggiunti alla lingua solo nel 1993. Ciò ha permesso finalmente di esprimere la modularità al di sopra della classe e del file.

Relazione tra classe interna ed esterna

Quindi l'annidamento di classi consente di gestire l'ambito e nascondere i dettagli di implementazione.

Se la classe nidificata è pubblica, un approccio valido alternativo sarebbe quello di mettere la classe esterna e quella interna in uno spazio dei nomi intermedio.

Inoltre, Bjarne Stroustrup raccomanda per classi generiche che: " I progettisti di una classe generica dovrebbero considerare attentamente la relazione tra i suoi parametri di tipo e le sue classi nidificate, se una classe interna non dipende da tutti i parametri di tipo, dovrebbe essere spostata all'esterno e sostituita con un alias che minimizzi le dipendenze. ".

Quindi, se dovessi dare accesso alla classe interna agli interni della classe esterna, dovresti infrangere i principi di incapsulamento se scegli di rifattare la tua soluzione su un'alternativa non annidata.

Conclusione

Considerando tutto ciò, appare chiaro che la classe interiore e la classe esterna dovrebbero essere considerate classi normali e obbedire al consueto principio dell'incapsulamento.

La classe interna dovrebbe quindi, se possibile, non essere un amico della classe esterna. Invece, chiama una funzione membro appropriata per impostare il flag :

class A
{
    bool bedromm_dirty; 
public: 
    void set_dirty(bool dirt); 
    inline bool get_dirty() const { return dirty; }

    class B  // would work also if not nested
    {        // no change needed if dirt would be managed with bit flags
    public:  
        void clean_room(class A&) { set_dirty(false); }
    };
};
    
risposta data 27.06.2016 - 00:15
fonte

Leggi altre domande sui tag