c++ - todas - ¿Por qué es llamar a una función miembro estática con. o-> sintaxis legal?
sintaxis de c++ pdf (5)
De la evolución de C ++ (pdf), sección 8. Funciones de miembro estático :
... También se observó que el código no portátil, como
((x*)0)->f();
Se utilizó para simular funciones miembro estáticas.
Así que mi conjetura es (basado en el patrón de razón para casi cualquier otra cosa sintáctica extraña) que permitieron invocar una función miembro estática cuando solo tenía el tipo para proporcionar compatibilidad hacia atrás con un idioma establecido pero roto.
Posible duplicado:
Método C ++ miembro estático llamada en instancia de clase
Hoy descubrí que algo que tenía por mucho tiempo (y me refiero a largo , como, por veinte años), creía ilegal en C ++ es realmente legal. A saber, llamar a una función miembro estática como si perteneciera a un objeto individual. Por ejemplo:
struct Foo
{
static void bar() { cout << "Whatever."; }
};
void caller()
{
Foo foo;
foo.bar(); // Legal -- what?
}
Normalmente veo que las funciones miembro estáticas se llaman estrictamente con "sintaxis de resolución de alcance", por lo tanto:
Foo::bar();
Esto tiene sentido, porque una función miembro estática no está asociada con ninguna instancia en particular de la clase y, por lo tanto, no esperaríamos que una instancia en particular esté "adjunta" sintácticamente a la llamada a la función.
Sin embargo, hoy descubrí que GCC 4.2, GCC 4.7.1 y Clang 3.1 (como una muestra aleatoria de compiladores) aceptan la sintaxis anterior, así como:
Foo* foo = new Foo;
foo->bar();
En mi caso particular, la legalidad de esta expresión condujo a un error de tiempo de ejecución, lo que me convenció de que la peculiaridad de esta sintaxis es más que un interés académico: tiene consecuencias prácticas.
¿Por qué C ++ permite que las funciones miembro estáticas se llamen como si fueran miembros directos de objetos individuales, es decir, mediante el uso de. o -> sintaxis adjunta a una instancia de objeto?
En El diseño y la evolución de C ++ en la página 288, Bjarne Stroustrup menciona que en los días previos a las funciones miembro estáticas, los programadores usaban hacks como ((X*)0)->f()
para llamar a funciones miembro que no necesitaban un objeto . Mi conjetura es que cuando se agregaron funciones miembro estáticas al lenguaje, se permitió el acceso a través de ->
para que los programadores con código como ese puedan cambiar de f
static
sin tener que buscar y cambiar cada uso del mismo.
Es así porque el estándar dice que así es como funciona. n3290 § 9.4 estados:
Se puede hacer referencia a un miembro estático de la clase X utilizando la expresión de id-calificado
X::s;
no es necesario usar la sintaxis de acceso de miembro de clase (5.2.5) para referirse a un miembro estático. Se puede hacer referencia a un miembro estático utilizando la sintaxis de acceso de miembro de clase, en cuyo caso se evalúa la expresión del objeto. [Ejemplo:
struct process { static void reschedule(); }; process& g(); void f() { process::reschedule(); // OK: no object necessary g().reschedule(); // g() is called }
ejemplo final]
Es de suponer que puede llamarlo en lugares donde puede que no sepa el tipo de clase de algo que el compilador sabe.
Digamos que tuve un montón de clases en las que cada una tiene un miembro estático que devolvió el nombre de la clase:
class Foo
{
static const char* ClassName() { return "Foo"; }
};
class Bar
{
static const char* ClassName() { return "Bar"; }
};
Entonces en todo mi código pude hacer cosas como:
Foo foo;
printf( "This is a %s/n", foo.ClassName() );
Sin tener que preocuparme por conocer la clase de mis objetos todo el tiempo. Esto sería muy conveniente al escribir plantillas por ejemplo.
Si no se suscribe a la escuela de causalidad "porque la norma lo dice", también sugiero que los métodos estáticos tienen la edad suficiente para provenir de un momento en que la gente realmente se preocupaba por la sobrecarga adicional de pasar this
argumento a una llamada de función. , por lo que hacer que las funciones puras sean "estáticas" como una optimización fue probablemente la furia en 1985.