Chiamata al metodo membro membro C ++ sull’istanza di class

Ecco un piccolo programma di test:

#include  class Test { public: static void DoCrash(){ std::cout<< "TEST IT!"<< std::endl; } }; int main() { Test k; k.DoCrash(); // calling a static method like a member method... std::system("pause"); return 0; } 

Su VS2008 + SP1 (vc9) compila bene: la console mostra solo “TEST IT!”.

Per quanto ne so, i metodi dei membri statici non dovrebbero essere richiamati su oggetti istanziati.

  1. Ho sbagliato? Questo codice è corretto dal punto di vista standard?
  2. Se è corretto, perché è così? Non riesco a trovare il motivo per cui sarebbe consentito, o forse è per aiutare a utilizzare il metodo “statico o meno” nei modelli?

Lo standard afferma che non è necessario chiamare il metodo attraverso un’istanza, ciò non significa che non è ansible farlo. C’è anche un esempio in cui viene utilizzato:

C ++ 03, 9.4 membri statici

Si può fare riferimento a un membro statico di class X usando l’espressione id qualificata X :: s; non è necessario utilizzare la syntax di accesso ai membri della class (5.2.5) per fare riferimento a un membro statico. Si può fare riferimento a un membro statico usando la syntax di accesso ai membri della class, nel qual caso viene valutata l’espressione dell’object.

 class process { public: static void reschedule(); }; process& g(); void f() { process::reschedule(); // OK: no object necessary g().reschedule(); // g() is called } 

Le funzioni statiche non hanno bisogno di un object instanciato per essere chiamato, quindi

 k.DoCrash(); 

si comporta esattamente come

 Test::DoCrash(); 

usando l’operatore di risoluzione scope (: 🙂 per determinare la funzione statica all’interno della class.

Si noti che in entrambi i casi il compilatore non inserisce this puntatore nello stack poiché la funzione statica non ne ha bisogno.

2) Se è corretto, perché è quello? Non riesco a trovare il motivo per cui sarebbe consentito, o forse è per aiutare a utilizzare il metodo “statico o meno” nei modelli?

È potenzialmente utile in diversi scenari:

  • [il metodo “statico o non” nei modelli “suggerisci:] quando molti tipi potrebbero essere stati specificati in un modello, e il modello vuole quindi richiamare il membro: i tipi che forniscono una funzione statica possono essere chiamati usando la stessa notazione come funzione membro – il primo può essere più efficiente (non this puntatore a passare / bind), mentre il secondo consente il dispiegamento ( virtual ) polimorfico e l’uso dei dati dei membri

  • minimizzare la manutenzione del codice

    • se una funzione si evolve dal richiedere dati specifici dell’istanza per non averne bisogno – e viene quindi resa static per consentire un uso semplice e privo di istanze e impedire l’uso accidentale dei dati di istanza – non è necessario aggiornare laboriosamente tutti i punti dell’utilizzo del client esistente

    • se il tipo è cambiato, la var.f() continua a utilizzare la funzione del tipo var , mentre Type::f() potrebbe richiedere la correzione manuale

  • quando si ha una chiamata di espressione o funzione che restituisce un valore e si desidera richiamare la funzione static (potenzialmente o sempre), il . la notazione può impedire che tu debba usare decltype o un modello di supporto per ottenere l’accesso al tipo, solo così puoi usare la :: notation

  • a volte il nome della variabile è molto più breve, più conveniente, o nominato in un modo più auto-documentante

i metodi statici possono essere chiamati anche usando un object della class, proprio come si può fare in Java. Tuttavia, non dovresti farlo. Utilizzare l’operatore scope come Test::DoCrash(); Forse pensi ai namespace:

 namespace Test { void DoCrash() { std::cout < < "Crashed!!" << std::endl; } }; 

che può essere chiamato solo da Test::DoCrash(); dall'esterno di tale spazio dei nomi se la funzione non viene importata esplicitamente utilizzando una using directive/declaration nell'ambito del chiamante.