Saltar a contenido

Última actualización:2026-10-12

static en C++: miembros estáticos y tiempo de vida

Sobre el autor

Cuenta pública de WeChat:

wechat

Cuando se usa con distintos tipos, la palabra clave static tiene significados diferentes. Podemos usar la palabra clave static para:

Variables estáticas: variables dentro de una función, variables dentro de una clase

Miembros de clase estáticos: objetos de clase y funciones dentro de una clase

Veamos ahora en detalle estos usos de static:

Variables estáticas

  • Variables estáticas en una función

Cuando una variable se declara static, el espacio se asigna durante todo el ciclo de vida del programa. Aunque se llame a la función varias veces, el espacio de la variable estática se asigna una sola vez, y el valor de la variable de la llamada anterior se transmite a la siguiente llamada de la función. Esto resulta muy útil en C / C++ o en cualquier otra aplicación que necesite almacenar el estado previo de una función.

#include <iostream> 
#include <string> 
using namespace std; 

void demo() 
{ 
    // static variable 
    static int count = 0; 
    cout << count << " "; 

    // value is updated and 
    // will be carried to next 
    // function calls 
    count++; 
} 

int main() 
{ 
    for (int i=0; i<5; i++)  
        demo(); 
    return 0; 
} 

Salida:

0 1 2 3 4 

Puede ver en el programa anterior que la variable count se declaró static. Por eso su valor se transmite a través de las llamadas a la función. Cada vez que se llama a la función, no se inicializa la variable de conteo.

  • Variables estáticas en una clase

Como las variables declaradas static se inicializan una sola vez, debido a que su espacio se asigna en un almacenamiento estático separado, las variables estáticas de una clase son compartidas por los objetos. No puede haber varias copias de la misma variable estática para objetos distintos. También por esta razón, las variables estáticas no pueden inicializarse con el constructor.

#include<iostream> 
using namespace std; 

class Apple 
{ 
public: 
    static int i; 

    Apple() 
    { 
        // Do nothing 
    }; 
}; 

int main() 
{ 
Apple obj1; 
Apple obj2; 
obj1.i =2; 
obj2.i = 3; 

// prints value of i 
cout << obj1.i<<" "<<obj2.i; 
} 

Puede ver en el programa anterior que intentamos crear varias copias de la variable estática i para varios objetos. Pero eso no ocurre. Por lo tanto, las variables estáticas de una clase deben inicializarse explícitamente por el usuario, fuera de la clase, usando el nombre de la clase y el operador de resolución de ámbito, como se muestra a continuación:

#include<iostream> 
using namespace std; 

class Apple 
{ 
public: 
    static int i; 

    Apple() 
    { 
        // Do nothing 
    }; 
}; 

int Apple::i = 1; 

int main() 
{ 
    Apple obj; 
    // prints value of i 
    cout << obj.i; 
} 

Salida:

1

Miembros estáticos

  • Objetos de clase estáticos

Al igual que las variables, los objetos declarados static también tienen un ámbito que se extiende hasta el ciclo de vida del programa.

Considere el siguiente programa, donde el objeto no es estático.

#include<iostream> 
using namespace std; 

class Apple 
{ 
    int i; 
    public: 
        Apple() 
        { 
            i = 0; 
            cout << "Inside Constructor\n"; 
        } 
        ~Apple() 
        { 
            cout << "Inside Destructor\n"; 
        } 
}; 

int main() 
{ 
    int x = 0; 
    if (x==0) 
    { 
        Apple obj; 
    } 
    cout << "End of main\n"; 
} 

Salida:

Inside Constructor
Inside Destructor
End of main

En el programa anterior, el objeto se declara no estático dentro del bloque if. Por eso el ámbito de la variable queda limitado al bloque if. Así, al crearse el objeto se invoca al constructor, y al salir del bloque if se invoca al destructor, porque el ámbito del objeto está limitado al bloque if donde se declaró. Si declaramos el objeto como estático, veamos ahora cómo cambia la salida.

#include<iostream> 
using namespace std; 

class Apple 
{ 
    int i; 
    public: 
        Apple() 
        { 
            i = 0; 
            cout << "Inside Constructor\n"; 
        } 
        ~Apple() 
        { 
            cout << "Inside Destructor\n"; 
        } 
}; 

int main() 
{ 
    int x = 0; 
    if (x==0) 
    { 
        static Apple obj; 
    } 
    cout << "End of main\n"; 
} 

Salida:

Inside Constructor
End of main
Inside Destructor

Puede ver claramente el cambio en la salida. Ahora el destructor se invoca después de que termine main. Esto se debe a que el ámbito de un objeto estático abarca todo el ciclo de vida del programa.

  • Funciones estáticas en una clase

Al igual que los miembros de datos estáticos o las variables estáticas de una clase, las funciones miembro estáticas no dependen de los objetos de la clase. Se nos permite invocar una función miembro estática usando un objeto y el operador '.'. Pero se recomienda invocar a los miembros estáticos usando el nombre de la clase y el operador de resolución de ámbito.

A las funciones miembro estáticas solo se les permite acceder a miembros de datos estáticos u otras funciones miembro estáticas; no pueden acceder a los miembros de datos no estáticos ni a las funciones miembro de la clase.

#include<iostream> 
using namespace std; 

class Apple 
{ 
    public: 
        // static member function 
        static void printMsg() 
        {
            cout<<"Welcome to Apple!"; 
        }
}; 

// main function 
int main() 
{ 
    // invoking a static member function 
    Apple::printMsg(); 
} 

Salida:

Welcome to Apple!

Restringir el ámbito de acceso static también sirve para restringir el ámbito de acceso (de forma similar al espacio de nombres anónimo). Tomado del issue: https://github.com/Light-City/CPlusPlusThings/issues/142

// source1.cpp
extern void sayHello();
const char* msg = "Hello World!\n";
int main()
{
    sayHello();
    return 0;
}

// source2.cpp
#include <cstdio>
extern char* msg;
void sayHello()
{
    printf("%s", msg);
}
g++ puede compilar con normalidad estos dos archivos de código e imprimir Hello World!, pero si se añade static a msg en source1.cpp, se produce el error de compilación undefined reference to 'msg':
// source1.cpp
extern void sayHello();
static const char* msg = "Hello World!\n";
int main()
{
    sayHello();
    return 0;
}

Temas relacionados

Comentarios