C ++ Llamada al método miembro estático en la instancia de clase

Aquí hay un pequeño progtwig de prueba:

#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; } 

En VS2008 + SP1 (vc9) comstack bien: la consola simplemente muestra “¡PRUEBA!”.

Por lo que yo sé, los métodos de miembros estáticos no deberían invocarse en objetos instanciados.

  1. ¿Me equivoco? ¿Este código es correcto desde el punto de vista estándar?
  2. Si es correcto, ¿por qué es eso? No puedo encontrar por qué estaría permitido, o tal vez es para ayudar a usar el método “estático o no” en las plantillas.

La norma establece que no es necesario llamar al método a través de una instancia, eso no significa que no pueda hacerlo. Incluso hay un ejemplo donde se usa:

C ++ 03, 9.4 miembros estáticos

Se puede hacer referencia a un miembro estático s de clase X utilizando la expresión de id. Calificada X :: s; no es necesario utilizar la syntax de acceso de los miembros de la clase (5.2.5) para referirse a un miembro estático. Se puede hacer referencia a un miembro estático utilizando la syntax de acceso de miembro de clase, en cuyo caso se evalúa la expresión de objeto.

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

Las funciones estáticas no necesitan un objeto instanciado para ser llamado, por lo

 k.DoCrash(); 

se comporta exactamente igual que

 Test::DoCrash(); 

utilizando el operador de resolución de scope (: 🙂 para determinar la función estática dentro de la clase.

Tenga en cuenta que, en ambos casos, el comstackdor no coloca this puntero en la stack, ya que la función estática no lo necesita.

2) Si es correcto, ¿por qué? No puedo encontrar por qué estaría permitido, o tal vez es para ayudar a usar el método “estático o no” en las plantillas.

Es potencialmente útil en varios escenarios:

  • [el método ” estático o no ” en plantillas ‘sugiere:] cuando se podrían haber especificado muchos tipos a una plantilla, y la plantilla entonces quiere invocar al miembro: los tipos que proporcionan una función estática se pueden llamar usando la misma notación como función miembro: la primera puede ser más eficiente (no this puntero para pasar / enlazar), mientras que la segunda permite el despacho polimórfico ( virtual ) y el uso de los datos de los miembros.

  • minimizando el mantenimiento del código

    • si una función evoluciona de necesitar datos específicos de instancia a no necesitarla y, por lo tanto, static para permitir un uso fácil sin instancia y evitar el uso accidental de datos de instancia, no es necesario actualizar todos los puntos del uso del cliente existente

    • si el tipo ha cambiado, la invocación var.f() continúa usando la función del tipo var , mientras que Type::f() puede necesitar corrección manual

  • cuando tiene una llamada de expresión o función que devuelve un valor y desea invocar la función static (potencial o permanente), el . la notación puede evitar que necesite usar decltype o una plantilla de apoyo para acceder al tipo, solo para que pueda usar la :: notación

  • A veces, el nombre de la variable es mucho más corto, más conveniente o se nombra de una manera más auto documentada

los métodos estáticos se pueden llamar también usando un objeto de la clase, al igual que se puede hacer en Java. Sin embargo, no deberías hacer esto. Utilice el operador de ámbito como Test::DoCrash(); Quizás pienses en espacios de nombres:

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

que solo puede ser llamado por Test::DoCrash(); desde fuera de ese espacio de nombres si la función no se importa explícitamente utilizando una using directive/declaration en el scope de la persona que llama.