Última atualização:2026-10-12
Membros estáticos e tempo de vida com static em C++¶
Sobre o autor¶
Conta oficial do 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:
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:
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:
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:
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:
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);
}
// source1.cpp
extern void sayHello();
static const char* msg = "Hello World!\n";
int main()
{
sayHello();
return 0;
}
Tópicos relacionados¶
- Funções virtuais puras e classes abstratas em C++ | C++那些事
- Asserções com assert em C++ | C++那些事
- Bit fields em C++ | C++那些事
- Implementando polimorfismo de C++ em linguagem C | C++那些事
- Constantes e modificadores com const em C++ | C++那些事
- A família completa do const em C++ | C++那些事
- O operador de desreferência * em C++ | C++那些事
- Inicialização e atribuição em C++ | C++那些事
- Formas de retornar múltiplos valores em C++ | C++那些事
- A palavra-chave mutable em C++ | C++那些事