2015-07-08 10 views
13

sto cercando di capire il motivo per cui il seguente è un errore:funzione di membro con il collegamento statico

class Foobar { 
public: 
    static void do_something(); 
}; 

static void Foobar::do_something() {} // Error! 

int main() { 
    Foobar::do_something(); 
} 

Questa errori con "l'errore: non può dichiarare la funzione di membro 'static void Foobar :: fai_qualcosa()' per avere collegamento statico "in g ++ e" errore: 'statico' può essere specificato solo all'interno della definizione della classe "in clang ++.

Capisco che il modo per risolvere questo problema è rimuovere "statico" nella definizione di do_qualcosa in linea 6. Tuttavia, non capisco perché questo è un problema. È una ragione banale, come "la grammatica del C++ detta così", o è qualcosa di più complicato?

+0

Possibile duplicato di [Errore funzioni membro statico; Come scrivere correttamente la firma?] (Https://stackoverflow.com/questions/8130066/static-member-functions-error-how-to-properly-write-the-signature) –

risposta

29

Penso che il problema qui sia che la parola chiave static ha diversi significati in C++ e il codice che hai scritto sopra li usa in due modi diversi.

Nel contesto delle funzioni membro, static significa "questa funzione membro non ha un oggetto destinatario. È fondamentalmente una funzione normale che è nidificata all'interno dell'ambito della classe".

Nel contesto delle dichiarazioni di funzione, static significa "questa funzione ha ambito solo per questo file e non può essere chiamata da altre posizioni".

Quando implementato la funzione scrivendo

static void Foobar::do_something() {} // Error! 

il compilatore ha interpretato la static qui per significare "Sto implementando questa funzione membro, e voglio fare quella funzione locale proprio a questo file." Ciò non è consentito in C++ perché provoca una certa confusione: se più file diversi hanno tutti definito la propria implementazione di una funzione membro e quindi li hanno dichiarati static per evitare collisioni al collegamento, chiamare la stessa funzione membro da posizioni diverse comporterebbe un comportamento diverso!

Fortunatamente, come avrete notato, c'è una soluzione semplice: basta cancellare la parola chiave static dalla definizione:

void Foobar::do_something() {} // Should be good to go! 

Questo è perfettamente bene perché il compilatore sa già che do_something è una funzione static membro, dal momento che l'ho detto prima.

Spero che questo aiuti!

+1

Questo ha senso, grazie! Suppongo che il compilatore possa distinguere tra static void some_function() {...} e static void Foobar :: some_method() {...} e trattarli in modo diverso, ma renderebbe più difficile l'analisi da parte degli umani poiché i due hanno semantica diversa e sintassi molto simile. Non sono molto contento della soluzione, dal momento che rende più difficile vedere che un metodo è statico osservando la sua implementazione (senza commenti), ma vabbè. –

+0

Quando si saggia 'È fondamentalmente una funzione normale che è annidata all'interno della portata della classe 'per normale intendi globale? – TheLogicGuy