Classi o spazi dei nomi annidati

2

Perché hanno bisogno di spazi dei nomi quando abbiamo classi annidate. Ciò che può essere fatto attraverso i namespace, può anche essere raggiunto attraverso le classi annidate.

quindi non capisco il ragionamento di avere spazi dei nomi?

    
posta Huzaifa 02.01.2014 - 00:55
fonte

6 risposte

11

Bene, attualmente la differenza principale è che uno spazio dei nomi è progettato per essere convertito in file separati. Se provi ad aggiungere una nuova classe nidificata a una classe, ottieni:

test1.cpp:3:7: error: redefinition of ‘class NamespaceClass’

Tuttavia, funziona solo in questo modo perché è stato definito in questo modo. Non sarebbe così difficile rielaborare il compilatore per aggiungere ad una classe in certi modi quando vede quella che ora è una ridefinizione.

Il motivo per cui non lo è è che uno spazio dei nomi e una classe sono concettualmente due cose diverse, usate per ragioni diverse. Una classe è pensata per essere istanziata e viene utilizzata per creare una strong coesione tra una struttura di dati e i metodi associati. Uno spazio dei nomi è pensato per raccogliere liberamente i moduli per facilitare la condivisione di gruppi di diversi file senza causare conflitti di denominazione.

Sì, puoi approssimare il comportamento di uno usando l'altro, ma questo non li rende uguali. Se hai usato una classe con la ridefinizione al posto di namespace, avresti problemi come:

  • Dover esaminare tutti i file di intestazione usando quella classe per ottenere la sua intera definizione, incluso determinare se è istantanea o meno.
  • Vogliamo usare un nome che denoti il suo scopo come spazio dei nomi, come StdNamespace invece di solo std .
  • Hai bisogno di una sorta di sintassi per indurti a entrare quando ridefinite casualmente una classe quando il compilatore pensa semplicemente di aumentarla come uno spazio dei nomi.

Quando aggiungi tutti i casi speciali che dovresti gestire per seguire veramente il principio di apertura, puoi anche chiamarlo spazio dei nomi.

    
risposta data 02.01.2014 - 03:20
fonte
5

Oltre alla risposta di Karl, penso che ci sia anche una grande differenza semantica.

Con gli spazi dei nomi, si raggruppano le classi correlate. Questo è in genere un obiettivo per mantenere alta la coesione. Con la classe nidificata, la nuova classe è principalmente correlata alla classe contenente, ma può non essere correlata alle classi nidificate "fratelli".

Questo oltre al fatto che le classi devono essere istanziate ma i namespace inclusi ne fanno due concetti diversi.

    
risposta data 02.01.2014 - 08:09
fonte
2

Bene, un vantaggio è che potresti avere dozzine di classi in uno spazio dei nomi. Hai considerato come sarebbe stato con le classi annidate? Voglio dire, puoi fare alcune cose con classi parziali in C #, ma il caso generale è piuttosto brutto. Penso che gli spazi dei nomi siano lì per raggruppare le funzionalità e portarle a compimento, mentre le classi interne esistono per incapsulare più parti strettamente collegate di funzionalità in un unico pacchetto indivisibile.

    
risposta data 02.01.2014 - 02:43
fonte
2

Una classe è una definizione di un tipo.

Uno spazio dei nomi è un "contenitore" per un set correlato di questi tipi definiti.

In realtà due cose molto diverse che servono a scopi diversi. Solo perché puoi imitare l'uso di uno utilizzando un altro non significa che siano necessariamente intercambiabili.

Allo stesso modo, potrei usare una variabile String per memorizzare un numero. In alcuni casi, si comporterebbe allo stesso modo. Ma non è favorevole alle buone pratiche o addirittura usare queste caratteristiche come per le quali erano originariamente destinate.

    
risposta data 06.01.2014 - 10:45
fonte
1

La cosa sintattica che fa la grande differenza è che la definizione di struc non è avvincente: iniziano con { e finiscono con } ea quel punto non possono essere "riaperti" per aggiungere altri membri .

Lo spazio dei nomi, al contrario, può essere "riaperto" ed esteso

// file F1.h
namespace A 
{ /* some defs */ }

//file F2.h
namespace A 
{ /* some other more defs */ }

e può quindi essere distribuito su molte intestazioni diverse ciascuna fornendo un insieme chiuso di classi.

Se includi sia F1.h anf F2.h, ottieni tutte le loro definizioni in A. Questo è difficile (o addirittura impossibile, senza trucchi di preprocessing complessi) con struct & Classe.

Dal lato inverso, struct può essere templato, lo spazio dei nomi non può.

Se le classi avrebbero potuto essere "riaperte ed estese" e gli spazi dei nomi sarebbero stati tepletizzati, allora i due concetti degenererebbero in uno solo.

Ma le "classi riapertura" (pensate al c # partial ) a causa del "meccanismo di inclusione del testo" e delle "unità di traduzione multiple" di C ++ (che non è un'importazione simbolica) porteranno a diverse unità di traduzione che vedono in modo diverso classi definite. Se queste diverse unità di traduzione vanno a formare un singolo artefatto (uno stesso eseguibile), non sarebbe possibile definire una dimensione coerente e un ordine coerente dei membri. (non che questo, per le variabili globali dello spazio dei nomi, che agiscono come i membri della classe nell'analogia dello spazio dei nomi di classe, porti al noto "fiasco dell'inizializzazione globale", dando un ordine di inizializzazione imprevedibile)

Da qui la necessità di namespace di raccogliere nomi senza un meccanismo di composizione / incapsulamento.

    
risposta data 06.01.2014 - 10:05
fonte
-3

In C #, sono molto simili.

namespace my_group {}

static class my_group {} // namespace

I namespace supportano la parola chiave using e lo stesso spazio dei nomi può estendersi su più file, tuttavia penso che non possano essere definiti all'interno di una classe statica.

    
risposta data 02.01.2014 - 02:11
fonte

Leggi altre domande sui tag