variable must initialize functions c++ static

must - static functions class c++



¿Por qué las definiciones de funciones miembro estáticas no tienen la palabra clave "estática"? (4)

Según este enlace en la palabra clave "estática" en C ++:

La palabra clave estática solo se usa con la declaración de un miembro estático, dentro de la definición de la clase, pero no con la definición de ese miembro estático .

¿Por qué está prohibida la palabra clave estática en las definiciones de función miembro? Entiendo que volver a declarar una función como ''estático'' en su definición es redundante. Pero usarlo debería ser inofensivo durante la compilación de la definición de la función, ya que no da lugar a ningún tipo de ambigüedad. Entonces, ¿por qué los compiladores lo prohíben?


Conjetura salvaje, pero si la definición tiene estática, podría interpretarse como una variable de ámbito de archivo en el sentido C.


Debe comprender la diferencia entre la declaración y la implementación, y eso responderá a su pregunta:

Declaración: ¿Cómo se ven las funciones y los métodos de C ++ antes de compilar el programa? Se coloca en un archivo de cabecera (archivo .h).

Implementación: Es como el compilador vincula una declaración a una tarea real en código binario. La implementación puede compilarse sobre la marcha (desde archivos fuente, .cpp o .cxx o .cc), o puede compilarse (desde bibliotecas compartidas o archivos de objetos).

Volviendo ahora a su pregunta, cuando declara algo como estático, es algo que no está relacionado con la implementación, sino que está relacionado con la forma en que el compilador ve la declinación al compilar el código. Por ejemplo, si etiqueta las funciones en los archivos fuente como "estáticas", entonces eso no tiene sentido, porque esa información no se puede llevar a objetos compilados y bibliotecas compartidas. ¿Por qué permitirlo? Por el contrario, solo podría causar ambigüedad.

Por el mismo motivo, los parámetros predeterminados deben ir al encabezado, no a los archivos fuente. Porque los archivos fuente (que contienen implementaciones) no pueden llevar la información de parámetros predeterminada a un objeto compilado.


El punto es que la static tiene varios significados muy diferentes:

class Foo { static void bar(); }

Aquí, la palabra clave static significa que la bar funciones está asociada con la clase Foo , pero no se invoca en una instancia de Foo . Este significado de static está fuertemente conectado a la orientación del objeto. Sin embargo, la declaración

static void bar();

significa algo muy diferente: significa que la bar solo es visible en el alcance del archivo, la función no puede ser llamada directamente desde otras unidades de compilación.

Verá, si dice static en la declaración de clase, no tiene sentido restringir más tarde la función al alcance del archivo. Y si tiene una función static (con alcance de archivo), no tiene sentido publicarla como parte de una definición de clase en un archivo de encabezado público. Los dos significados son tan diferentes, que prácticamente se excluyen el uno al otro.

static tiene aún más significados distintos:

void bar() { static int hiddenGlobal = 42; }

es otro significado, que es similar, pero no idéntico a

class Foo { static int classGlobal = 6*7; }

Cuando se programa, las palabras no siempre tienen el mismo significado en todos los contextos.


Hay ambigüedad bien La misma definición no necesita ser para una función de miembro en absoluto.

Considera esto:

namespace foo { static void bar(); } static void foo::bar() { }

foo::bar debe definirse con el mismo especificador de vinculación.

Sin embargo, para las funciones de miembro, static no es un especificador de vinculación. Si se permitió, la exactitud de la definición de foo::bar dependerá mucho del contexto de lo que sea foo . Denegar la static de hecho alivia la carga del compilador.

Extenderlo a los miembros en general, en contraposición a solo funciones de miembro, es una cuestión de consistencia.