Vida útil do objeto e duração de armazenamento em C ++

Vida útil do objeto e duração de armazenamento em C ++
Ao criar um objeto, sua localização na memória deve ser estabelecida antes de ser inicializada. Inicialização significa colocar valor no local. A vida útil de um objeto começa logo após a inicialização. Quando um objeto morre, sua localização (armazenamento), que o objeto ocupou é liberado e o computador é desligado ou o armazenamento é retomado (usado) por outro objeto. Liberar um meio de armazenamento, tornando o identificador ou ponteiro que ocupava o armazenamento, inválido. A vida útil de um objeto termina, quando seu armazenamento é liberado.

É necessário algum tempo para criar um objeto. É necessário algum tempo para matar um objeto. Ao falar sobre um objeto, duas coisas estão envolvidas: o local que é o armazenamento e o valor. O significado da vida útil e da duração do armazenamento é semelhante; Mas a duração é vista mais do ponto de vista da localização do que do ponto de vista do valor. A duração do armazenamento é a hora de quando um local é associado a um objeto ao momento em que o local é dissociado do objeto.

O restante deste artigo ilustra a vida útil do objeto e explica brevemente as diferentes durações de armazenamento. Você deve ter conhecimento básico em C ++ para entender este artigo. Você também deve ter conhecimento em escopo C ++.

Conteúdo do artigo

  • Ilustração da vida útil do objeto
  • Duração do armazenamento
  • Duração automática de armazenamento
  • Duração dinâmica de armazenamento
  • Duração do armazenamento estático
  • Duração do armazenamento de rosca
  • Conclusão

Ilustração da vida útil do objeto

Considere o seguinte programa:

#incluir
usando namespace std;
int main ()

se (1 == 1)

int x;
x = 1;
char y;
y = 'a';
cout << x << y << '\n';

retornar 0;

A saída é, 1a .

A vida de um objeto chega ao fim, quando sai do escopo. A vida útil do objeto X começa em "x = 1;" e termina no final do scope IF-Local. A vida útil do objeto Y começa em "y = 'a';" e termina no final do scope IF-Local. Antes de ambos os objetos morrem, eles são empregados na declaração de cout .

Duração do armazenamento

A duração do armazenamento é determinada por um dos seguintes esquemas: duração automática de armazenamento; duração de armazenamento dinâmico; duração de armazenamento estático; Duração do armazenamento de rosca. Categorias de duração de armazenamento, também se aplicam a referências.

Duração automática de armazenamento

Se uma variável, não for declarada explicitamente como estática, thread_local ou extern, essa variável possui duração automática de armazenamento. Exemplos estão x e y acima. A duração de tais variáveis ​​termina quando saem do escopo. O programa a seguir ilustra a duração automática de armazenamento para uma referência e um ponteiro, no escopo global.

#incluir
usando namespace std;
int x = 1;
int & m = x;
char y = 'a';
char* n = & y;
int main ()

cout << m << *n << '\n';
retornar 0;

A saída é, 1a .

A duração de m começa em "int & m = x;" e termina no final do programa. A duração de n começa em "char* n = & y;" e termina no final do programa.

Duração dinâmica de armazenamento

Loja grátis

Em um computador moderno, mais de um programa pode estar em execução ao mesmo tempo. Cada programa tem sua própria parte da memória. O restante da memória que não está sendo usado por nenhum programa é conhecido como loja gratuita. A expressão a seguir é usada para retornar um local para um número inteiro da loja gratuita

novo int

Este local (armazenamento) para o número inteiro, devolvido, ainda deve ser identificado por atribuição a um ponteiro. O código a seguir ilustra como usar o ponteiro na loja gratuita:

int *ptrint = new int;
*pTrint = 12;
cout<< *ptrInt <<'\n';

A saída é 12 .

Para acabar com a vida do objeto, use a expressão de exclusão da seguinte forma:

excluir pTrint;

O argumento para a expressão de exclusão é um ponteiro. O código a seguir ilustra seu uso:

int *ptrint = new int;
*pTrint = 12;
excluir pTrint;

Um ponteiro criado com a nova expressão e excluído com a expressão de exclusão é de duração dinâmica de armazenamento. Este ponteiro morre quando sai do escopo ou é excluído. A duração do objeto no código anterior começa em "*pTrint = 12;" e termina no final da região declarativa (escopo). Há mais nas novas expressões e excluídas do que foi discutido aqui - veja mais tarde.

Duração do armazenamento estático

Objeto estático

Um objeto declarado estático, se comporta como o objeto comum, exceto que sua duração de armazenamento começa a partir de quando é inicializado até o final do programa. Não pode ser visto fora de seu escopo, mas pode ser indiretamente empregado de fora de seu escopo.

Considere o seguinte programa, que deve contar de 1 a 5 (não teste o programa):

#incluir
usando namespace std;
int fn ()

int stc = 1;
cout << " << stc;
stc = stc + 1;
If (STC> 5)
retornar 0;
fn ();

int main ()

fn ();
retornar 0;

A saída é 1 1 1 1 1 1 1… e nunca realmente acaba. A definição da função é uma função recorrente; o que significa que continua se chamando até que uma condição seja atendida.

A solução é tornar o objeto STC estático. Depois que um objeto estático foi inicializado, seu valor não pode ser alterado até que o programa termine. O programa a seguir (que você pode testar), que é o mesmo que o acima, mas agora com o STC feito estático, conta de 1 a 5:

#incluir
usando namespace std;
int fn ()

estático int stc = 1;
cout << " << stc;
stc = stc + 1;
If (STC> 5)
retornar 0;
fn ();

int main ()

fn ();
retornar 0;

A saída é: 1 2 3 4 5 .

Nota: A duração de um objeto estático começa quando o objeto foi inicializado e termina no final do programa. Enquanto isso, o objeto pode ser usado indiretamente, de um escopo diferente. Depois que um objeto estático foi inicializado, seu valor inicial não pode ser alterado, mesmo que sua definição seja reavaliada. No código acima, o STC não é redefinido, na próxima vez que for chamado. Na próxima vez que for chamado, é incrementado por "STC = STC + 1;".

Membro de dados estático

Um conjunto de variáveis ​​e função relacionadas pode ser colocado em uma unidade generalizada chamada classe. Se as variáveis ​​recebem valores particulares, a classe se tornará um objeto. No entanto, um objeto não é criado apenas atribuindo valores à variável. A classe é instanciada para obter um objeto; e cada objeto criado tem seu próprio nome diferente de outros objetos da mesma classe. O programa a seguir mostra uma classe, chamada Thecla e um objeto, chamado OBJ; Ele também mostra como o objeto é instanciado e usado na função principal ():

#incluir
usando namespace std;
CLASSE THECLA

público:
int num;
Void Func (Char Cha, Const Char *str)
cout << "There are " <<
num << " books worth " <<
Cha << str << " in the store." << '\n';

;
int main ()

Thecla obj;
obj.num = 12;
obj.func ('$', "500");
retornar 0;

A saída é:

Existem 12 livros no valor de US $ 500 na loja.

Observe que, para atribuir o valor de 12 à variável num, o objeto deve ser instanciado, antes que a tarefa possa ocorrer. É possível para o programador atribuir o valor sem instantar (criando) um objeto. Para conseguir isso, a variável, num terá que ser declarada como estática. Em seguida, será acessado como "thecla :: num" sem o nome do objeto, mas com o nome da classe. O programa a seguir ilustra o seguinte:

#incluir
usando namespace std;
CLASSE THECLA

público:
estático const int num = 12;
Void Func (Char Cha, Const Char *str)
cout << "There are " << num <<
"Livros que valem a pena" << cha << str <<
" na loja." << '\n';

;
int main ()

cout << TheCla::num << '\n';
Thecla obj;
obj.func ('$', "500");
retornar 0;

A saída é:

12
Existem 12 livros no valor de US $ 500 na loja.

Observe que, para acessar o membro de dados, num em main (), o operador de resolução de escopo, :: teve que ser usado. Também não que a variável, o NUM tivesse que ser constante e inicializado na descrição da classe (definição).

Função estática do membro

Observe que, na lista de programas anteriores acima, para usar a função func em main (), um objeto teve que ser instanciado. É possível para o programador chamar a função sem instantar (criando) um objeto. Para conseguir isso, a definição de função deve ser precedida com a palavra "estática". Em seguida, será acessado como "thecla :: func ()" sem o nome do objeto, mas com o nome da classe. O programa a seguir ilustra isso para membro estático de dados e função estática do membro:

#incluir
usando namespace std;
CLASSE THECLA

público:
estático const int num = 12;
Func estático Void (Char Cha, Const Char *str)
cout << "There are " << num <<
"Livros que valem a pena" << cha << str <<
" na loja." << '\n';

;
int main ()

Thecla :: func ('$', "500");
retornar 0;

A saída é:

Existem 12 livros no valor de US $ 500 na loja.

Duração do armazenamento de rosca

Thread como um recurso em C ++, ainda não foi implementado pelo compilador G ++. Portanto, em vez de explicar isso, a citação da especificação C ++ é dada da seguinte forma:

  1. Todas as variáveis ​​declaradas com a palavra -chave Thread_local têm duração de armazenamento de threads. O armazenamento para essas entidades deve durar a duração do fio em que são criados. Existe um objeto ou referência distinta por thread, e o uso do nome declarado refere -se à entidade associada ao tópico atual.
  2. Uma variável com duração de armazenamento de roscas deve ser inicializada antes do seu primeiro uso de ODR e, se construído, deve ser destruído na saída do thread.”

Conclusão

A vida útil de um objeto começa quando sua inicialização é concluída e termina quando seu armazenamento é liberado. A duração dinâmica do armazenamento começa quando o armazenamento criado por (novo tipo) é inicializado e termina quando o objeto sai do escopo ou é excluído por "excluir ponteiro". A duração de um objeto estático começa quando o objeto foi inicializado e termina no final do programa. Depois que um objeto estático foi inicializado, seu valor inicial não pode ser alterado, mesmo que sua definição seja reavaliada. Membros de dados estáticos e membros da função estática são acessados ​​fora da descrição da classe com "ClassName :: Name".