Superiorità dello spazio dei nomi senza nome rispetto a statica?


Risposte:


134

Ti riferisci sostanzialmente alla sezione §7.3.1.1 / 2 della norma C ++ 03,

L'uso della parola chiave statica è deprecato quando si dichiarano oggetti nell'ambito di uno spazio dei nomi; lo spazio dei nomi senza nome fornisce un'alternativa superiore.

Si noti che questo paragrafo è già stato rimosso in C ++ 11. staticle funzioni per standard non sono più obsolete!

Tuttavia, gli spazi dei nomi senza nome sono superiori alla parola chiave statica, principalmente perché la parola chiave si staticapplica solo alle dichiarazioni e funzioni delle variabili , non ai tipi definiti dall'utente .

Il seguente codice è valido in C ++

   //legal code
   static int sample_function() { /* function body */ }
   static int sample_variable;

Ma questo codice NON è valido:

   //illegal code
   static class sample_class { /* class body */ };
   static struct sample_struct { /* struct body */ };

Quindi la soluzione è, unname-namespace, che è questo,

   //legal code
   namespace 
   {  
        class sample_class { /* class body */ };
        struct sample_struct { /* struct body */ };
   }

Spero che questo spieghi perché unnamed-namespaceè superiore a static.

Inoltre, si noti che l'uso della parola chiave statica è deprecato quando si dichiarano oggetti nell'ambito di uno spazio dei nomi (secondo lo standard).


11
Più in generale, uno spazio dei nomi senza nome consente il collegamento esterno. Questo è ciò che abilita la dichiarazione di classe da unità locale a traduzione. Consente inoltre, ad esempio, la costante di stringa di collegamento esterno, da utilizzare come argomento modello.
Saluti e hth. - Alf

10
Come notato da Fred Nurk in un'altra risposta, sembra che questa deprecatedosservazione sia stata rimossa dall'ultimo CCD 0x FCD (n3225).
Matthieu M.

36
Stai rispondendo alla tua domanda e stai dicendo grazie a te stesso: -o
manpreet singh

12
Quale sarebbe la differenza dalla semplice definizione della classe nel cpp (nessuno spazio dei nomi anonimo, nessuno statico)?
Luchian Grigore,

6
@LuchianGrigore I problemi di collegamento nel caso 2 .cppstanno definendo una classe con lo stesso nome.
Xaqq,

8

C'è un problema interessante legato a questo:

Supponiamo che tu usi una staticparola chiave o senza nome namespaceper rendere alcune funzioni interne al modulo (unità di traduzione), poiché questa funzione è pensata per essere utilizzata internamente dal modulo e non accessibile al di fuori di esso. (Gli Innominati namespacehanno il vantaggio di rendere anche i dati e le definizioni dei tipi interni, oltre alle funzioni).

Con il passare del tempo il file sorgente dell'implementazione del modulo si ingrandisce e si desidera dividerlo in diversi file sorgente separati, il che consentirebbe di organizzare meglio il codice, trovare le definizioni più velocemente e compilare in modo indipendente.

Ma ora stai affrontando un problema: quelle funzioni non possono più essere staticnel modulo, perché in staticrealtà non si riferiscono al modulo , ma al file sorgente (unità di traduzione). Sei costretto a renderli non staticper consentire l'accesso a loro da altre parti (file oggetto) di quel modulo. Ma questo significa anche che non sono più nascosti / privati ​​al modulo: avendo un collegamento esterno, è possibile accedervi da altri moduli, che non era la tua intenzione originale.

Senza nome namespacenon risolverebbe questo problema, perché è anche definito per un determinato file di origine (unità di traduzione) e non è possibile accedervi dall'esterno.

Sarebbe bello se si potesse specificare che alcuni namespacesono private, cioè qualsiasi cosa sia definita in esso, è destinata ad essere utilizzata internamente dal modulo a cui appartiene. Ma ovviamente C ++ non ha un concetto come "moduli", solo "unità di traduzione", strettamente legate ai file di origine.


3
Sarebbe comunque un trucco e una soluzione limitata, ma potresti includere i file cpp con le funzioni statiche interne o spaziate nei tuoi file cpp 'principali'. Quindi escludi questi file cpp 'satellite' dalla compilazione e il gioco è fatto. L'unico problema se hai due o più file cpp 'principali' ed entrambi vogliono usare quella fantastica funzione da uno dei file cpp 'satellite' ...
Sergey,

la soluzione non è utilizzare l'ereditarietà con privato / protetto / pubblico con funzioni statiche?
Ali,

C ++ 20 introduce i moduli, il che risolve il problema.
LF

4

Lo standard C ++ recita nella sezione 7.3.1.1 Spazi dei nomi senza nome, paragrafo 2:

L'uso della parola chiave statica è deprecato quando si dichiarano oggetti in un ambito dello spazio dei nomi, lo spazio dei nomi senza nome fornisce un'alternativa superiore.

Statico si applica solo ai nomi di oggetti, funzioni e sindacati anonimi, non al tipo di dichiarazioni.


5
No, non lo fa. Una bozza ha fatto. E un'altra bozza subito dopo ha ripristinato questo sciocco cambiamento.
underscore_d
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.