2009-12-09 9 views
5

Che cosa è generalmente considerato uno stile di codifica buono in C++ in cui si utilizzano i tipi dalla libreria standard? Ad esempio, se ho una direttiva using namespace std; ci si aspetterebbe ancora di vedere i tipi di libreria completamente qualificati in questo modo: std::string o è accettabile utilizzare semplicemente string come identificativo del tipo?C++ stile di codifica buono - qualifica sempre completamente i tipi di libreria?

Se si qualificano pienamente, è possibile espanderne la logica?

+2

Si noti che 'std :: STRING' non è un nome completo,' :: std :: STRING' è pienamente qualificato d'altra parte . – dalle

risposta

14

qualificarsi completamente nei file di intestazione. importa lo spazio dei nomi nei file .cpp.

mantiene il namespace globale dall'essere ingombra da un semplice #include

+0

Impedisce inoltre di forzare lo spazio dei nomi su qualcuno se decide di includere il file di intestazione. Può creare una certa confusione se si stanno chiedendo "dove in nome di Dio ho usato quel namespace?" e non pensano di guardare il codice di qualcun altro che hanno incluso. –

+2

Direi facoltativamente importare lo spazio dei nomi nei file sorgente, ma qui il punto critico e corretto non è mai posto in una dichiarazione "using namespace" in un file di intestazione. –

13

Preferirei utilizzando:

using std::string; 
string whatever; 

che portare pienamente lo spazio dei nomi in

In ogni caso gli sviluppatori di biblioteca dovrebbe evitare nomi dei tipi che sono in conflitto con quelli standard, anche se string probabilmente è abbastanza comune..

Per le librerie diverse dallo standard, mi piace qualificare se lo spazio dei nomi di nidificazione non è troppo lungo, se lo si digita semplicemente in un nome significativo che include il nome della libreria o qualcosa del genere.

+2

L'intero punto dello spazio dei nomi è che non devi preoccuparti dei nomi usati da altre librerie, anche quelle standard. –

+4

Scegliere i nomi già definiti nello standard per la propria libreria è una pessima idea. Non è illegale, è solo una cattiva idea, visto che chiunque legga il vettore penserà a std :: vector. –

1

Generalmente assegnerò tutti i nomi agli spazi dei nomi invece di utilizzare using namespace x principalmente quando gestisco i file di intestazione. I file di origine potrebbero non volere che lo spazio dei nomi sia assunto e non dovresti forzarlo sui file di origine che includono il tuo file di intestazione.

Io faccio entrambi using namespace x e qualificano completamente gli spazi dei nomi in base a una chiamata personale per decidere se riutilizzerò il tipo più volte o meno nei file di origine.

+0

accidenti, mi ha battuto al pugno di 42 secondi – sdellysse

+0

Penso che questo sia sbagliato. Non dovresti mai usare x; in qualsiasi file di intestazione. Se questi utenti mitici non vogliono dover fornire directory di utilizzo adeguate, la loro sfortuna è dura. –

+0

@Neil Butterworth: Sono d'accordo, e ho modificato la dichiarazione per essere più energica. –

1

namespace è sostanzialmente introdotta per ridurre al minimo i conflitti nomi di simboli come la funzione, di classe, e le variabili. Va bene che tu usi semplicemente string rispetto a std::string a meno che la tua biblioteca non abbia string nel suo spazio. Non utilizzo virtualmente uno spazio dei nomi molto comune come std.

0

Domanda totalmente soggettiva: Direi accettabile solo per usare stringa. IDE/compilatore sono abbastanza intelligenti per scoprire cosa intendi. Se si hanno oggetti con lo stesso nome, ad esempio 2 tipi di stringa. Quindi hai un problema diverso perché il compilatore non saprà cosa intendi e il programmatore non saprà cosa intendi.

Un altro motivo per non utilizzare i nomi di libreria è dovuto al fatto di ingombrare il codice: In C# system.xml.xmltextreader è semplicemente eccessivo. XmlTextReader è sufficiente per capire cosa sia. Dove è situato è quasi mai il problema

+0

L'IDE può essere "abbastanza intelligente", ma il compilatore non lo sarà. –

+0

Perché il compilatore non si accorge subito che la stringa è la stessa di std :: string se si usa 'using namespace std'. il compilatore non sarà intelligente se hai più tipi con lo stesso nome, vedi 2a riga. – RvdK

1

io tendo a rispettare due regole:

  • Nei file di intestazione, si vuole qualificare i nomi dei tipi con il pieno spazio dei nomi e mai, mai voglia di mettere qualcosa di simile using namespace std; in quanto ciò può causare problemi interessanti a causa di conflitti di denominazione imprevisti che è necessario rintracciare alle 1:00.
  • Nei file di implementazione, tendo a inserire simboli che utilizzo da altri spazi dei nomi utilizzando using std::string; o simili.In realtà, non sono coerente al 100% con questo dato che spesso non inserisco lo spazio dei nomi std, ma inserisco gli spazi dei nomi del progetto ma questa è una preferenza personale. Mai, mai, mettere mai sopra using namespace somethingorother; #include.
+1

Io uso queste regole con un'aggiunta: l'ambito massimo consentito per una clausola "using" in un file di implementazione è una funzione. – paxos1977

+0

Questa non è una cattiva idea; Ho iniziato a usarlo ma lo faccio dipendente dall'uso generale. Ad esempio, l'utilizzo di std :: string all'ambito della funzione può diventare un po 'noioso, pertanto tende a essere spostato verso l'ambito del file. –

0

In generale, preferisco (1) per direttiva using come using std::string; string hello; come quello che Jimenez ha notato in precedenza; (2) Io uso anche un namespace anonimo, quindi utilizzare l'direttiva using namespace per importare tutti i nomi nel mio namespace anonima come questo namespace { using namespace std; // or using std::string string blah_blah_blah; }

+0

Solo per quello che vale, un 'using direttiva' è uno come' using namespace x'. Uno come 'using std :: string' è un' using declaration'. –

+0

Grazie Jerry, apprezza la correzione. –

3

Proprio per quello che vale, ci sono alcune cose che puoi fare estraendo uno spazio dei nomi con una direttiva using che non è possibile eseguire con nomi di qualifica. L'esempio canonico probabilmente sta scrivendo una funzione di ordinamento generica. Se è stato definito un swap per il tipo da ordinare, si desidera utilizzarlo, ma se non ha uno swap proprio, si desidera utilizzare std::swap.

Per fare questo, si può scrivere il codice come:

using namespace std; 
// ... 
template <class T> 
void my_sort(std::vector<T> &x) { 
    // ... 
    if (x[j] < x[k]) 
     swap(x[j], x[k]); 

Ora, se c'è un swap nello spazio dei nomi di qualsiasi tipo che viene ordinato, sarà trovata da argomento di ricerca dipendente. Se non lo è, verrà trovato std::swap perché lo hai reso visibile con la direttiva using.

6

L'intero punto deve essere per evitare confusione e generare codice chiaro. L'omissione degli spazi dei nomi può in alcuni casi offuscare l'origine di una funzione o di una classe, ma l'aggiunta di spazi dei nomi sempre completi può diventare insopportabile.

  • Evitare using namespace nei file di intestazione
  • Usa using namespace in origine per le librerie "ovvie" (ad esempio std, o la biblioteca per testare in un programma di test)
  • È possibile alias namespace nell'origine per tenerlo breve e leggibile:

Esempio

namespace fs = boost::filesystem; 
bool fileExists = fs::exists(fs::path(filePath)); 

EDIT, per completezza: using namespace nei file di intestazione inquina file di origine con namepaces importati in un non-ovvio modo ('spiegazioni nuf di questo già in questa discussione).

0

Sono sempre pienamente qualificato nelle intestazioni. Non ho mai inserito le istruzioni "using ..." nelle intestazioni.

La mia preferenza è quella di qualificare completamente nel file di implementazione e, se lo standard dell'organizzazione è quello di incorporare "con ..." dichiarazioni all'interno dei file di implementazione Lo farò,

0

Se non si qualificano pienamente , avrai grandi problemi quando sposti i metodi in linea dalle intestazioni ai file CPP o viceversa, e sicuramente vuoi uno stile tra i tuoi progetti.

In caso contrario, non è un problema, a volte mi qualifico nonostante l'istruzione using esistente.In intestazioni è un problema, se non è nel campo di applicazione:

// somefile.h 
namespace VisionMap 
{ 
    namespace X 
    { 
     using namespace Y; // Does not impact the header's user, 
           // as would if it was in the global scope. 
    } 
} 
Problemi correlati