2012-05-08 32 views
20

Sono uno sviluppatore Java e sono piuttosto nuovo in C++. Devo implementare una sorta di classe di utilità e stavo pensando di implementare i metodi come statici. Tuttavia, mi sono imbattuto in this stackoverflow question riguardo le funzioni dello spazio dei nomi rispetto al metodo statico e le funzioni dello spazio dei nomi apprently sono l'approccio preferito. Quindi vorrei sapere se c'è qualche articolo o esempio su come implementare la funzione namespace. E.g, come dovrei dichiarare le funzioni dello spazio dei nomi nel file di intestazione? L'intestazione dovrebbe contenere solo definizioni di funzioni come il file di intestazione di classe e le implementazioni dovrebbero essere nel file cpp, o dovrei immediatamente implementare le funzioni nel file di intestazione?Funzioni spazio dei nomi C++

Fondamentalmente, sto cercando di implementare un'applicazione per analizzare un file di testo che contiene alcuni comandi. Quindi sto pensando di implementare metodi di supporto statico per gestire l'elaborazione del testo. E.g readCommand (linea di stringa). Per favore fatemi sapere se sono nella direzione sbagliata. Grazie

+1

C++ opera una distinzione abbastanza netta tra le funzioni e le classi . Non è chiaro dalla tua domanda quale ti interessa usare. – Shep

+0

Ciao Shep, Grazie per il commento. Ho aggiunto più dettagli alla mia domanda. Risponde alla tua domanda? –

risposta

19

come devo dichiarare le funzioni dello spazio dei nomi nel file di intestazione?

namespace MON { 
// extern: 
t_ret func(const t_param& pValue); 
// 'inline': 
inline t_ret inline_func(const t_param& pValue) { ... } 
} // << MON 

Dovrebbe intestazione contengono solo definizioni di funzioni come il file di intestazione di classe e le implementazioni dovrebbero essere in un file cpp, o dovrei subito implementare funzioni nel file di intestazione?

che dipende dal fatto che si desideri (potenzialmente) in linea o esportati. questo spesso si riduce a minimizzare le dipendenze.

per espandere sull'esportazione o inline:

che ci si favoriscono spesso una funzione extern per ridurre al minimo le dipendenze in C++. ciò equivale a separare la definizione della dichiarazione in un metodo di classe:

file.hpp

namespace MON { 
// extern: 
t_ret func(const t_param& pValue); 
} // << MON 

file.cpp

#include "hefty_stuff.hpp" 

MON::t_ret MON::func(const t_param& pValue) { ... } 

tuttavia, è in momenti critici per la definizione per essere visibile in alcuni casi, spesso per le prestazioni o quando si conosce la dimensione è importante e l'intestazione non è inclusa in molti luoghi. quindi, la variante inline è anche un'opzione.

una funzione inline può ancora essere esportata, e può essere inline come richiesto - tuttavia, qualsiasi copia di funzione inline può essere unita (in particolare, l'implementazione è libera di assumere tutte le definizioni sono uguali e tutte le copie della funzione sono non necessario).

con le definizioni esportate, è possibile limitare in modo selettivo (o mettere in quarantena) le dipendenze di inclusione. ovvero, #include "hefty_stuff.hpp" non deve essere nell'intestazione per utilizzare le funzioni in file.hpp.


Fondamentalmente, io sto cercando di implementare un'applicazione per analizzare un file di testo che contiene alcuni comandi. Quindi sto pensando di implementare metodi di supporto statico per gestire l'elaborazione del testo.

beh, static dovrebbe essere evitato qui. C++ usa la regola a una definizione. static causerà solo un sacco di copie inutili. Inoltre, uno spazio dei nomi anonimo è l'approccio C++ per la funzione di c static:

namespace { 
t_ret func(const t_param& pValue) { ... } 
} // << anon 

nota: namespace anonimi possono anche provocare copie inutili. il motivo per cui le utilizzi come sostituto di una funzione statica è se vuoi o devi scostarti dalla regola a una definizione e non vuoi dichiarare il simbolo in un ambito che può essere "risolto".


il punto finale riguarda le dichiarazioni template<>. con i modelli, la definizione deve essere visibile dove usata, a meno che il compilatore non supporti i modelli extern. per i modelli, è possibile ottenere la visibilità delle definizioni in più modi. in genere, le persone dichiarano semplicemente la definizione, oppure aggiungono un'intestazione per le definizioni che sono incluse alla fine dell'intestazione o quando necessario. con i modelli, non è necessario dichiarare le funzioni inline per evitare errori di definizione multipli.

+0

Grazie mille Justin. Potresti spiegare un po 'di più sul punto "potenzialmente in linea o esportato" o indicarmi qualche articolo che dovrei leggere su di esso? –

+2

@KHein yup - expanded – justin

+0

@Justin, hai dimenticato di menzionare le funzioni relative ai modelli. – Griwes

1

come devo dichiarare le funzioni dello spazio dei nomi nel file di intestazione?

namespace YourNamespace 
{ 
    void fun1(); 
    void fun2(); 
} 

caso di intestazione contengono solo definizioni di funzioni come il file di intestazione di classe e le implementazioni dovrebbero essere in un file cpp, o dovrei subito implementare funzioni nel file di intestazione?

Se le funzioni nello spazio dei nomi sono statiche, è possibile implementare funzioni nel file di intestazione oppure implementarle nel file cpp.

+0

Non completamente corretto, è possibile implementare le funzioni non statiche nell'intestazione. – juanchopanza

+1

@juanchopanza: solo se li dichiarate 'in linea'. –

+0

@Kerrek SB: accetta –

12

È possibile dichiarare le funzioni nella testata:

namespace A { 
    void foo(); 
} 

e implementare nel cpp:

namespace A { 
    void foo() { std::cout << "foo!"; } 
} 

Si può anche mettere l'attuazione nell'intestazione, avendo cura di dichiararla inline per evitare di rompere il one definition rule:

namespace A { 
    inline void foo() { std::cout << "foo()!"; } 
} 

Non e che inserire l'implementazione nell'intestazione significa che il codice client ha una dipendenza di compilazione sull'implementazione, nonché sulle intestazioni utilizzate per l'implementazione. Nell'esempio sopra, il codice cliente ora dipende dall'intestazione, e se facciamo qualcosa di banale come aggiungere un punto esclamativo alla stampa, dobbiamo ricompilare, invece di ricollegare, tutto il codice cliente.

E 'molto importante per mettere le implementazioni di funzioni modello nell'intestazione o in un file incluso da l'intestazione, questi non possono andare nel cpp:

namespace B { 
    template <class T> 
    inline void foo(const T& t) { std::cout << t.name() << "\n"; } 
} 
+0

+1 per mettere implementazioni delle funzioni template nell'intestazione. La definizione deve essere visibile dove usata, a meno che il compilatore non supporti i modelli extern. – milesma

Problemi correlati