2010-03-17 12 views
25

Devo definire alcune stringhe costanti che verranno utilizzate solo da una classe. Mi sembra di avere tre opzioni:Dove inserisco stringhe costanti in C++: membri di classi statiche o namespace anonimi?

  1. Incorporare le stringhe direttamente nei luoghi in cui vengono utilizzate.

  2. li definiscono come membri privati ​​statica costante della classe:

    //A.h 
    class A { 
    private: 
        static const std::string f1; 
        static const std::string f2; 
        static const std::string f3; 
    }; 
    
    //A.cpp 
    const std::string f1 = "filename1"; 
    const std::string f2 = "filename2"; 
    const std::string f3 = "filename3"; 
    
    //strings are used in this file 
    
  3. definirli in uno spazio dei nomi anonimo nel file cpp:

    //A.cpp 
    namespace { 
        const std::string f1 = "filename1"; 
        const std::string f2 = "filename2"; 
        const std::string f3 = "filename3"; 
    } 
    
    //strings are used in this file 
    

Alla luce di queste opzioni, che uno consiglieresti e perché? Grazie.

+0

Grazie per la formattazione. – stone

+6

Si noti che questo è pericoloso se si chiama la funzione che utilizza queste stringhe da altre unità di traduzione prima dell'avvio principale: la funzione potrebbe quindi accedere agli oggetti stringa prima che siano stati creati. Per questo motivo, mi sbarazzerei degli oggetti const std :: string, e uso 'char const f1 [] =" nomefile ";' per questo. –

+0

@litb: Sembra che tu stia dicendo che è più sicuro utilizzare il tipo di carattere primitivo rispetto all'oggetto stringa in questo caso? Posso sapere la ragione di questo? – jasonline

risposta

21

Li inserirò nello spazio dei nomi anonimo nel file CPP. Li rende privati ​​dell'implementazione e allo stesso tempo li rende visibili alle funzioni non membri che fanno parte dell'implementazione (come operator<<).

+0

Grazie per l'impegno. Sono anche incline a questa opzione. A queste corde piacerebbe molto essere costante. Ma se in seguito ho deciso di cambiare uno dei nomi di file, posso farlo facilmente senza preoccuparmi di ricomporre tutto ciò che includeva il file di intestazione. – stone

+0

Vale la pena notare che, anche se li definisci come comandi statici all'interno della classe, il testo effettivo dovrà ancora trovarsi nel file di implementazione. Pertanto, la modifica dei nomi di file non richiede la ricompilazione di alcunché eccetto quello stesso file. –

+0

Hai ragione, Dennis. Farà la differenza in termini di compling quando aggiungi/elimina queste costanti. La loro modifica dovrebbe essere la stessa. – stone

2

Se le stringhe devono essere viste dagli utenti della classe, inserirle nella classe. Altrimenti, nascondili nello spazio dei nomi senza nome del file di implementazione.

5

Se vengono utilizzati solo in un singolo file, non è necessario esporli al mondo esterno includendoli nel file di intestazione.

Se vengono utilizzati e verranno sempre utilizzati solo in un singolo luogo, non c'è davvero alcun motivo per non limitarsi a scriverli come valori letterali in cui devono essere utilizzati.

Se sono utilizzati in più posizioni nel cpp, vorrei andare per lo spazio dei nomi anonimo.

Un'altra opzione che non si menziona è definirli come variabili statiche all'interno di cpp. questo è in qualche modo equivalente all'opzione namespace anonimo e più simile a C che a C++.

3

Membri statici della classe.

Se sono usati in più posti da una classe, di solito è più facile mantenere le cose organizzate - e in seguito trovare dove hai definito tutto - se le tenga definite nella classe che li usa. Definirli sul posto li rende difficili da localizzare e successivamente modificare. E opterei per la classe specifica sullo spazio dei nomi anonimo per una definizione e un uso della classe più puliti.

0

Delle tre opzioni, l'unica da evitare è la # 1. Non usare i cookie magici nel tuo codice. Inserendo le costanti in uno spazio dei nomi o in una classe, è più semplice estendere e mantenere il codice in futuro.

Se le vostre costanti sono di natura globale, quindi tra 2 e 3, importa poco. Ciò che conta è che tu ne scelga uno e lo segua. Ma se hai delle costanti che si applicano a una particolare classe, allora dovrebbero far parte di quella classe.

Personalmente, userei un namespace per la maggior parte delle cose.

0

Penso che il vero problema sia: le stringhe sono realmente utilizzate solo internamente durante l'implementazione della classe o vengono utilizzate altrove.

Per essere davvero pignoli, proverei a mantenere l'interfaccia della classe più pulita possibile, quindi se le stringhe del nome file non dovrebbero interessare il mondo "esterno". Li nasconderò internamente solo nel file .cpp. E in tal caso non penso che mi preoccuperei del namespace, ma semplicemente mantenere le cose "statiche" (cioè interne al file .cpp).

2

Se utilizzato solo nel file cpp della classe, non v'è alcuna necessità di utilizzare uno spazio dei nomi di qualsiasi tipo, dire semplicemente:

const std::string f1 = "filename1"; 
const std::string f2 = "filename2"; 
const std::string f3 = "filename3"; 

L'abuso di spazi dei nomi sembra essere la cosa nuova - non posso vedere personalmente l'attrazione.

+1

Ma ciò potrebbe causare errori del linker se ci sono nomi f1, f2, ecc in altre unità di compilazione. Ecco perché esistono spazi dei nomi anonimi. –

+0

C'è qualche differenza tra queste definizioni e uno spazio dei nomi anonimo? Mi sembra che siano implicitamente definiti come "statici". – stone

+2

@Nemanja No, non lo farà. Un oggetto const dichiarato nello spazio dei nomi è locale all'unità di traduzione. –

0

Tuttavia, è necessario fare attenzione: non raccomanderei l'uso di oggetti statici std :: string, invece di usare char statico *. La ragione di ciò è dovuta a potenziali problemi con l'ordine di inizializzazione. Supponiamo di avere un'istanza statica di una classe il cui costruttore fa riferimento alla stringa A::f1. Non vi è alcuna garanzia che lo A::f1 sia stato ancora costruito e si verifichi un arresto anomalo, o peggio, nessun arresto anomalo ma dati falsi.

Tracciare i bug di ordine di inizializzazione può essere piuttosto sgradevole, e tutto può sembrare buono in un progetto, ma poi si potrebbe costruire un altro progetto usando le stesse librerie e le sottili differenze nell'ordine di collegamento causeranno questo errore apparire misteriosamente.

0

Basta avere le stringhe const sull'ambito del file nel file di implementazione, lo spazio dei nomi anonimo non è necessario per limitare il loro uso solo a quella classe.

C++ 003 Standard C.1.2 Clause 3: concetti di base

Change: A name of file scope that is explicitly declared const, and not explicitly declared extern, has internal linkage, while in C it would have external linkage 

Nota: Lo spazio dei nomi anonimo aiuta ridurre i conflitti di denominazione.