2012-06-07 25 views
14

Si supponga che ho dichiarato una funzione (o classe, non importa) in un file di intestazione, che fa parte del namespace foo:Best practice: usare lo spazio dei nomi o riaprire lo spazio dei nomi?

namespace foo 
{ 
    void bar(); 
    … 
} 

Per molto tempo sono stato la riapertura dello spazio dei nomi quando ho è stata la definizione della funzione in un file cpp:

namespace foo 
{ 
void bar() 
{ 
    doSomething(); 
    … 
} 
} 

questo è perché ho imparato in questo modo ed è stato utilizzato in un progetto su cui stavo lavorando. Non ho mai veramente se su di esso fino a poco tempo, quando sono incappato in un progetto che ha usato la direttiva using invece:

using namespace foo; 

void bar() 
{ 
    doSomething(); 
    … 
} 

Infine c'è una possibilità di utilizzare il nome completo. Lo trovo piuttosto noioso, specialmente quando sono coinvolte classi con molti membri. A mio avviso, non ha molto senso quando tutto il contenuto del file fa parte di uno spazio dei nomi.

void foo::bar() 
{ 
    doSomething(); 
    … 
} 

Quindi la mia domanda è quale si dovrebbe preferire e perché? Soprattutto per quanto riguarda le prime due opzioni (usando la direttiva vs riapri lo spazio dei nomi).

+3

vorrei dire che è una questione di preferenze personali.Io stesso uso un mix tra la prima e l'ultima delle vostre alternative. –

+5

Sono d'accordo che si tratta di preferenze personali. 'foo :: bar' è ripetitivo ma greppable, anche se potrebbe essere irrilevante se le persone cercano sempre la tua fonte usando un IDE. –

+2

È come chiedere se sia meglio usare tab o 4 spazi. ** Non preoccuparti delle piccole cose. ** :) – LihO

risposta

13

Penso che il modo più pulito è ri-apertura dello spazio dei nomi, e ho gli argomenti per sostenerla:

  • con la seconda opzione, con la direttiva using, non è chiaro che si stai implementando un metodo in quel namespace. Potresti anche implementare una funzione gratuita che utilizza qualcosa dal namespace.
  • la terza opzione viene in genere utilizzata per l'implementazione delle funzioni membro della classe. Se si guarda direttamente nel file cpp, non è chiaro se si sta implementando una funzione da un namespace a meno che non si sappia che lo spazio dei nomi esiste. La prima cosa che viene in mente è che stai implementando una funzione membro della classe.
  • il primo è il più chiaro. Si apre lo spazio dei nomi e si definisce una funzione al suo interno. La funzione è parte dello spazio dei nomi e questa è l'implementazione.
+0

Il tuo secondo punto elenco sembra dire "Non faccio X, quindi la prima cosa che mi viene in mente è Y". Y non viene necessariamente prima nella mente delle persone che fanno X, quindi una volta che si segue la convenzione il problema scompare. Inoltre, se non riesci a capire la differenza tra i nomi dei nomi dei nomi e delle classi, prendi in considerazione la scelta di nomi migliori; –

+0

@SteveJessop Non penso che sia un punto valido. 'X :: foo()' è il * solo * modo in cui puoi definire un metodo di classe (a meno che non sia in linea). Mentre per gli spazi dei nomi hai un'alternativa. Allora perché usare due stili per rappresentare cose diverse, quando puoi usare stili diversi con intenti chiari? –

+1

sembra esserci un assioma sottostante, che è di vitale importanza far apparire le cose più diverse possibili. Penso che altre cose possano essere più importanti, quindi non accetto quell'assioma (se lo facessi, userei C, dato che non ha sovraccarico di funzioni). –

6

Anche se using namespace è la soluzione più pigra (e quindi la più allettante), spesso non è una buona idea. Inoltre quello che Luchian dice sulle dichiarazioni di funzione è ambiguo (qualcuno di nuovo al progetto non saprebbe se questa è una funzione autonoma o uno nel namespace), e il fatto che potresti introdurre un nome nello spazio dei nomi più tardi, scontrandoti con uno sei usando ora, ho un'altra ragione per cui suggerirei di usare il terzo metodo.

Utilizzando il terzo metodo, si fornisce il codice più consistenza. Se A è all'interno di B, lo si definirà sempre con A::B. Se A è una classe e B una funzione nella classe, scrivere type A::B(args). Se A è una classe e B un membro statico, si scriverebbe nuovamente type A::B = value. Ora A è uno spazio dei nomi, ma è sempre lo stesso concetto: B è definito all'interno di A, pertanto è più coerente utilizzare nuovamente A::B.

(c'è un ulteriore bonus di ricerca-abilità, se il vostro editor è per esempio ViM)

Problemi correlati