Ir para o conteúdo

Última atualização:2026-10-12

Membros estáticos e tempo de vida com static em C++

Sobre o autor

Conta oficial do WeChat:

wechat

Quando usada com tipos diferentes, a palavra-chave static tem significados diferentes. Podemos usar a palavra-chave static:

Variáveis estáticas: variáveis em funções, variáveis em classes

Membros estáticos de classes: objetos de classe e funções em classes

Agora vejamos em detalhe esses usos de static:

Variáveis estáticas

  • Variáveis estáticas em funções

Quando uma variável é declarada static, o espaço é alocado durante todo o ciclo de vida do programa. Mesmo que a função seja chamada várias vezes, o espaço da variável estática é alocado uma única vez, e o valor da variável de uma chamada anterior é levado para a chamada seguinte da função. Isso é muito útil em C/C++ ou em qualquer outra aplicação que precise armazenar o estado anterior da função.

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

Saída:

0 1 2 3 4 

Você pode ver, no programa acima, que a variável count foi declarada static; por isso, o seu valor é transmitido entre as chamadas da função. A cada chamada da função, a variável count não é inicializada de novo.

  • Variáveis estáticas em classes

Como as variáveis declaradas static são inicializadas apenas uma vez — porque seu espaço é alocado em um armazenamento estático separado —, as variáveis estáticas de uma classe ** são compartilhadas pelos objetos**. Não pode haver múltiplas cópias da mesma variável estática para objetos diferentes. É também por esse motivo que variáveis estáticas não podem ser inicializadas com o construtor.

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

Você pode ver, no programa acima, que tentamos criar múltiplas cópias da variável estática i para vários objetos — o que não aconteceu. Por isso, as variáveis estáticas de uma classe devem ser inicializadas explicitamente pelo usuário, fora da classe, usando o nome da classe e o operador de resolução de escopo, assim:

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

Saída:

1

Membros estáticos

  • Objetos de classe estáticos

Assim como as variáveis, os objetos também têm escopo até o fim do ciclo de vida do programa quando declarados static.

Considere o programa a seguir, em que o objeto não é 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"; 
} 

Saída:

Inside Constructor
Inside Destructor
End of main

No programa acima, o objeto é declarado como não estático dentro do bloco if; portanto, o escopo da variável fica restrito ao bloco if. Assim, quando o objeto é criado, o construtor é chamado e, ao mesmo tempo que o controle sai do bloco if, o destrutor é chamado, porque o escopo do objeto se limita ao bloco if em que foi declarado. Se declararmos o objeto como estático, vejamos agora como a saída muda.

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

Saída:

Inside Constructor
End of main
Inside Destructor

Você pode ver claramente a mudança na saída: agora o destrutor é chamado depois do fim do main. Isso ocorre porque o escopo do objeto estático se estende por todo o ciclo de vida do programa.

  • Funções estáticas em classes

Assim como os membros de dados estáticos ou as variáveis estáticas de uma classe, as funções membro estáticas também não dependem dos objetos da classe. Somos autorizados a chamar funções membro estáticas usando um objeto e o '.'; mas é recomendado chamá-las usando o nome da classe e o operador de resolução de escopo.

As funções membro estáticas só podem acessar membros de dados estáticos ou outras funções membro estáticas; elas não conseguem acessar membros de dados ou funções membro não estáticas da classe.

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

Saída:

Welcome to Apple!

Restrição do escopo de acesso static também tem a função de restringir o escopo de acesso (semelhante a um namespace anônimo). Da 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);
}
O g++ compila normalmente esses dois arquivos de código e imprime Hello World!; mas, se for adicionado static ao msg de source1.cpp, ocorre o erro de compilação undefined reference to 'msg':
// source1.cpp
extern void sayHello();
static const char* msg = "Hello World!\n";
int main()
{
    sayHello();
    return 0;
}

Tópicos relacionados

Comentários