Creazione di uno spazio dei nomi C ++ nell'intestazione e nel sorgente (cpp)


90

C'è qualche differenza tra il wrapping sia dell'intestazione che del contenuto del file cpp in uno spazio dei nomi o il wrapping solo del contenuto dell'intestazione e quindi utilizzare lo spazio dei nomi nel file cpp?

Per differenza intendo qualsiasi tipo di penalizzazione delle prestazioni o semantica leggermente diversa che può causare problemi o qualsiasi cosa di cui devo essere a conoscenza.

Esempio:

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
namespace X
{
  void Foo::TheFunc()
  {
    return;
  }
}

VS

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
using namespace X;
{
  void Foo::TheFunc()
  {
    return;
  }
} 

Se non c'è differenza qual è la forma preferita e perché?

Risposte:


38

Lo spazio dei nomi è solo un modo per manipolare la firma della funzione in modo che non entrino in conflitto. Alcuni preferiscono il primo modo e altri preferiscono la seconda versione. Entrambe le versioni non hanno alcun effetto sulle prestazioni in fase di compilazione. Nota che gli spazi dei nomi sono solo un'entità in fase di compilazione.

L'unico problema che sorge con l'utilizzo dello spazio dei nomi è quando abbiamo gli stessi nomi di spazi dei nomi annidati (cioè) X::X::Foo. Ciò crea più confusione con o senza l'utilizzo di parole chiave.


56

La differenza tra "spazio dei nomi X" e "utilizzo dello spazio dei nomi X" è che nella prima tutte le nuove dichiarazioni saranno sotto lo spazio dei nomi mentre nella seconda no.

Nel tuo esempio non ci sono nuove dichiarazioni, quindi nessuna differenza, quindi nessun modo preferito.


Dipende dal progetto e dallo stile. Spesso c'è uno spazio dei nomi principale per un carico di file in un modulo e il secondo stile ha senso.
Nicholas Wilson

8

Non ci sono penalità per le prestazioni, poiché il risultato potrebbe essere lo stesso, ma inserire il tuo Foonello spazio dei nomi introduce implicitamente ambiguità nel caso in cui tu abbia Foos in spazi dei nomi diversi. Puoi ottenere il tuo codice fubar, infatti. Consiglierei di evitare l'utilizzo usingper questo scopo.

E hai un randagio {dopo using namespace;-)


Non lo chiamerei randagio, poiché corrisponde alla chiusura }alla fine. Tuttavia, definirei ridondante quella coppia di parentesi graffe;)
blubberdiblub

@blubberdiblub, la questione è stata curata, se è stata selezionata la versione originale, si dovrebbe chiamare randagi ;-)
Michael Krelin - hacker,

1

Se viene compilato anche il secondo, non dovrebbero esserci differenze. Gli spazi dei nomi vengono elaborati in fase di compilazione e non dovrebbero influire sulle azioni di runtime.

Ma per questioni di design, il secondo è orribile. Anche se si compila (non sono sicuro), non ha alcun senso.


1
Non penso che si compili, ma non perché ci sia una differenza, ma perché c'è un randagio {;-)
Michael Krelin - hacker

La differenza è che Foo :: TheFunc () è dichiarato nello spazio dei nomi globale, mentre è definito nello spazio dei nomi X.
bert-jan

1

Foo :: TheFunc () non è nello spazio dei nomi corretto nel caso VS. Usa 'void X :: Foo :: TheFunc () {}' per implementare la funzione nello spazio dei nomi corretto (X).


La domanda è un po 'vecchia, ma sai quali sono le conseguenze? cioè incontrerai problemi con il modo in cui il suo caso VS dichiara le funzioni nello spazio dei nomi, ma le definisce al di fuori di esso?
Adam Goodwin

1

Nel caso in cui avvolgi solo il contenuto .h devi scrivere usando lo spazio dei nomi ... nel file cpp altrimenti ogni volta lavori sullo spazio dei nomi valido. Normalmente si avvolgono sia i file .cpp che .h altrimenti si corre il rischio di utilizzare oggetti da un altro spazio dei nomi che potrebbe generare molti problemi.


0

Penso che la cosa giusta da fare qui sia usare lo spazio dei nomi per l'ambito.

namespace catagory
{
    enum status
    {
      none,
      active,
      paused
    }
};

void func()
{
    catagory::status status;
    status = category::active;
}

0

Se stai tentando di utilizzare le variabili dall'una all'altra, ti consiglio di esternalizzarle, quindi inizializzarle nel file sorgente in questo modo:

// [.hh]
namespace example
{
   extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
   int a, b, c;
}
// Then in the function below, you can init them as what you want: 
void reference
{
    example::a = 0;
}
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.