2012-02-06 7 views
5

Ho definito alcune funzioni (nessuna classe coinvolta qui) in un file * .cpp esterno e, naturalmente, esiste un file * .h appropriato.Shoud Uso spazi dei nomi senza nome nei file di implementazione?

Alcune delle funzioni nel file * .cpp vengono utilizzate solo solo nel file * .cpp in nessun altro punto.. Non sono nemmeno menzionati nel file * .h.

Devo inserire tali funzioni in uno spazio dei nomi senza nome o possono vivere proprio accanto alle altre funzioni? E se sì, perché dovrei aver bisogno di uno spazio dei nomi senza nome per loro? Non riesco a vedere un problema, dal momento che tali funzioni non sono accessibili dall'esterno.

+0

Perché non renderli "statici"? (come in una funzione C statica, non un metodo di classe statico) –

+1

@JamesMcLaughlin: beh in C++ 03 'static' è stato deprecato a tale scopo. Tuttavia, C++ 11 non lo deprezza. Ma 'static' e l'essere nello namespace senza nome significa cose diverse. 'static' gli darà il collegamento interno, quindi la funzione non può essere utilizzata per alcuni scopi. –

+0

Grazie per i vostri suggerimenti. Qualcuna di queste soluzioni, spazio dei nomi statico o non, è consigliata o preferita? – user1192880

risposta

9

Se si desidera che siano veramente privati ​​di tale unità di compilazione, inserirli in uno spazio dei nomi anonimo. Se non lo fai, qualcuno potrebbe dichiarare queste funzioni altrove e usarle esplicitamente.

Prendiamo il seguente esempio:

// library.cpp 

// a "private" function here, in that it is not declared anywhere 
void f() {} 

namespace 
{ 
    // same as above, except within an anonymous namespace 
    void g() {} 
} 

// client.cpp 

void f(); 

int main() 
{ 
    // Can call f(), it's been declared and is now effectively "public" 
    f(); 

    // compilation error, this has no idea what g() is, it's not declared 
    // in any scope that can be resolved here 
    g(); 

    return 0; 
} 
+0

Grazie! Non ero a conoscenza di quella "caratteristica". – user1192880

+0

Questo è il significato di 'static'. Gli spazi dei nomi anonimi forniscono questa funzionalità per le classi e le strutture. –

+0

La parola chiave 'static' protegge anche dalla collisione dei nomi con altre funzioni che possono esistere in altre parti del codice? Lo spazio dei nomi senza nome lo farà. – Chad

1

Credo che se non si vuole queste funzioni per essere visto dall'esterno li dichiarano come static.

+0

* "... visto da fuori ..." * - Da fuori di cosa? L'intestazione? L'unità di traduzione? – jww

4

La tua domanda può essere divisa in due:

1. "? Come posso nascondere funzioni globali"

Un modo semplice per farlo, è NON di mettere l'intestazione della funzione nel file di intestazione:

//============================ 
// Filename: "mylibrary.hpp" 
//============================ 
// Description: 
// Utility functions. 
//============================ 
#ifndef MYLIBRARY_H_INCLUDED 
#define MYLIBRARY_H_INCLUDED 
//============================ 

namespace MyLibrary 
{ 
    void DoSomething(); 
} // namespace MyLibrary 

//============================ 
#endif // MYLIBRARY_H_INCLUDED 
//============================ 

file di codice completa:

//============================ 
// Filename: "mylibrary.cpp" 
//============================ 
// Description: 
// Utility functions. 
//============================ 
// self header include 
#include "mylibrary.hpp" 
//============================ 

namespace MyLibrary 
{ 
    void DoSomethingBefore() 
    { 
     // ... 
    } 

    void DoSomethingAfter() 
    { 
     // ... 
    } 

    void DoSomethingConfirmed() 
    { 
     // ... 
    } 

    void DoSomething() 
    { 
     DoSomethingBefore(); 
     DoSomethingConfirmed(); 
     DoSomethingAfter(); 
    } 
} // namespace MyLibrary 

//============================ 
#endif // MYLIBRARY_H_INCLUDED 
//============================ 

Quando questo viene compilato , ottieni un file "mylibrary.o" o "mylibrary.obj". Puoi fornirlo ad altri sviluppatori come "mylibrary.hpp" e "mylibrary.obj", ma senza il file "mylibrary.cpp". La maggior parte dei compilatori "plain c"/"C++" può funzionare in questo modo.

Ci sono altri modi, leggere la sezione successiva.

2. "I namespace anonimi sono una buona tecnica per nascondere le funzioni globali?"

La tecnica "Namespace anonimi" è un altro modo per nascondere le funzioni globali.

C'è una domanda simile su:

Unnamed/anonymous namespaces vs. static functions

Ma, personalmente, non mi consiglia di questa tecnica, come la risposta "preferito".

Gli spazi dei nomi sono una di quelle cose che vorrei esistessero dall'inizio di "pure c" o "C++". Ma, "namespace anonimi" o "namespace senza nome", sembra strano da usare.

È come cercare di nascondere qualcosa e, più tardi, dimenticare, dove lo memorizzi.

3 Ulteriori suggerimenti

(a) vi suggerisco di utilizzare un unico principale RICHIESTO, non facoltativo, namespace non anonima per file. Può avere spazi dei nomi interni nidificati aggiuntivi. Ogni spazio dei nomi principale dovrebbe avere lo stesso id. come nome file, ma senza estensione file o suffisso file.

(b) Evitare namespace anonimi. È come immagazzinare cose in un magazzino, senza un indice.

(c) Utilizzare un'estensione di file o prefisso file nei file di intestazione, forse ".h" o ".hpp", anche se è un file C++. Lo standard dice che C++ non dovrebbe usare un'estensione di file o suffisso su file "C++", ma sono difficili da identificare o trovare sul filesystem.

Buona fortuna.

Problemi correlati