Para mí, el uso de la palabra clave static
en C y lenguajes como C # y Java son "falsos amigos" como "convertirse" en inglés y "bekommen" en alemán (= "obtener" en inglés), porque significan cosas diferentes.
En C static
significa que la función o variable solo es accesible a través de funciones dentro del mismo archivo fuente, comparable a private
funciones y miembros en C ++, Java y C #.
En C ++, Java y C # static
significa que los métodos no son miembros de una instancia de clase, sino que son más o menos como funciones de C más espacio de nombres.
En mi humilde opinión, estos dos conceptos son bastante diferentes, entonces, ¿por qué los diseñadores de C ++ y posteriores de Java y C # eligieron la static
palabra clave para ese comportamiento? ¿Hay una conexión lógica que echo de menos?
EDITAR
Sé que static
en C no gobierna la accesibilidad de una manera similar a private
C ++, pero puede usarse de esa manera, consulte https://stackoverflow.com/a/1479639/124983
Cabe destacar que C ++ tiene ambos usos
static
y creo que hay un tercero en alguna parte.En general, creo que el uso de C
static
no se corresponde en absoluto con el uso de la palabra en inglés, mientras que creo que,static
comostatic
variable miembro, tiene mucho más sentido.Recuerde que, como diseñador de lenguaje, tiene un incentivo justo para introducir menos palabras clave en el lenguaje, para no permitir menos código, especialmente cuando intenta ser compatible con C, como en C ++, y la
static
palabra clave ya existía, por lo que no pudieron romper ningún programa de C que intentara compilarse como C ++ reutilizándolo.Editar: Sabía que había un tercero. C tiene
static
variables de nivel de función . Elstatic
miembro es solo una versión con alcance de esta funcionalidad. Por lo tanto, ambos usos de sestatic
originan en C.fuente
static
, solo se enfoca en una clase en lugar de una función.static
tener tres usos en C (variable de alcance de función, alcance de unidad de compilación para variables, alcance de unidad de compilación para funciones). Realmente está haciendo las mismas dos cosas en estos tres casos (vinculación y duración), comparto su opinión al respecto. La vista de tres usos de la estática en C es más común, lamentablemente. Ayuda a las personas a entender cómo usarlo, pero no cómo funciona realmente.En C ++,
static
tiene los siguientes cuatro usos:Función global (nivel de archivo) y declaraciones de variables : con static, está especificando un enlace interno . Eso significa que el símbolo solo se usa en esa unidad de compilación (.cpp / cc / cualquier archivo, no un encabezado). Esto es a lo que se refiere como "privado".
Variables locales : la duración del almacenamiento estático especifica que la variable debe conservar su valor entre las llamadas a funciones.
Miembros de datos : los miembros de datos estáticos se comparten entre las instancias de la clase (es decir, solo hay una copia del miembro). Esto es similar a C # y Java estático.
Funciones miembro : las funciones miembro estáticas son funciones miembro que no tienen un
this
puntero implícito ; se pueden invocar sin una instancia. Esto también es muy parecido a C # o Java.Entonces, como puede ver, dejaron caer dos de los significados anteriores. Para el alcance, es bastante comprensible por qué: tanto C # como Java (e incluso C ++) se basan en espacios de nombres para hacerlo. C ++ probablemente tiene la función de enlace interno para compatibilidad con versiones anteriores. El abandono de las variables locales estáticas es probablemente doble: por una vez, puede ser difícil comprender completamente sus consecuencias, y estos lenguajes apuntan a la simplicidad. En segundo lugar, tanto Java como C # tienen un recolector de basura que (me imagino) causa dificultades para implementar dicho comportamiento.
fuente
static
(prefiriendo espacios de nombres anónimos) y luego, en su encarnación actual, C ++ 11 desaprobó el uso destatic
esto. (todos IIRC)C ++ lo tomó de C, porque a C ++ le gusta reutilizar las palabras clave existentes en lugar de introducir otras nuevas, para minimizar la ruptura del código existente.
Java y C # lo tomaron de C ++.
fuente
C
static
no gobierna la accesibilidad, y no es análogo aprivate
la forma en que sugiere.En el ámbito del archivo, gobierna la disponibilidad del nombre (símbolo del enlazador), no la cosa: puede pasar un puntero a una
static
función o global desde la unidad de traducción donde se define para codificar en otro archivo, y funcionará bien.La forma en C ++ de hacerlo (como dice DeadMG, la forma en C todavía está disponible también) es usar un espacio de nombres anónimo.
En el ámbito de la función, esencialmente reemplaza la variable local con una global que solo es accesible (¡por nombre de nuevo!) Dentro de esa función; esto es idéntico en C ++ (por lo tanto, no hay una manera más C ++ de hacerlo) .
En cuanto a por qué C ++ usó el
static
calificador para los miembros de la clase; Probablemente sea correcto decir que esto es para minimizar la cantidad de palabras clave nuevas introducidas. (Tenga en cuenta la reciente reutilización de auto para la comparación).Llamar a los datos por clase estáticos (de manera implícita, los datos por instancia son dinámicos ) me parece bastante intuitivo, pero como no recuerdo el proceso de formación de esa intuición, no puedo comentar objetivamente si tenía sentido al comenzar fuera.
fuente