C ++

Escopo em C ++

Escopo em C ++
Uma entidade em C ++ tem um nome, que pode ser declarado e / ou definido. Uma declaração é uma definição, mas uma definição não é necessariamente uma declaração. Uma definição aloca memória para a entidade nomeada, mas uma declaração pode ou não alocar memória para a entidade nomeada. Uma região declarativa é a maior parte de um programa em que o nome de uma entidade (variável) é válido. Essa região é chamada de escopo ou escopo potencial. Este artigo explica o escopo em C++. Além disso, é necessário conhecimento básico em C ++ para entender este artigo.

Conteúdo do Artigo

Região Declarativa e Escopo

Uma região declarativa é a maior parte de um texto de programa em que o nome de uma entidade é válido. É a região em que o nome não qualificado pode ser usado (visto) para se referir à mesma entidade. Considere o seguinte programa curto:

#incluir
usando namespace std;
void fn ()

int var = 3;
if (1 == 1)

cout<

int main ()

fn ();
return 0;

A função fn () tem dois blocos: um bloco interno para a condição if e um bloco externo para o corpo da função. O identificador, var, é introduzido e visto no bloco externo. Também é visto no bloco interno, com a declaração cout. Os blocos externos e internos são o escopo do nome, var.

No entanto, o nome, var, ainda pode ser usado para declarar uma entidade diferente, como um flutuante no bloco interno. O código a seguir ilustra isso:

#incluir
usando namespace std;
void fn ()

int var = 3;
if (1 == 1)

float var = 7.5;
cout<

int main ()

fn ();
return 0;

A saída é 7.5. Neste caso, o nome, var, não pode mais ser usado no bloco interno para se referir ao número inteiro de valor 3, que foi introduzido (declarado) no bloco externo. Esses blocos internos são referidos como escopo potencial para entidades declaradas no bloco externo.

Nota: Uma entidade do mesmo tipo, como a do bloco externo, ainda pode ser declarada no bloco interno. Porém, neste caso, o que é válido no bloco interno é a nova declaração e seu significado, enquanto a declaração antiga e seu significado fora do bloco interno permanecem válidos no bloco externo.

Uma declaração com o mesmo nome em um bloco interno normalmente substitui a declaração com o mesmo nome fora desse bloco interno. Os blocos internos podem aninhar outros blocos internos.

Âmbito global

Quando um programador apenas começa a digitar um arquivo, esse é o escopo global. O programa curto a seguir ilustra isso:

#incluir
usando namespace std;
float var = 9.4;
int main ()

cout <cout <<::var<<'\n';
return 0;

O resultado é:
9.4
9.4

Neste caso, a região declarativa ou escopo para var começa a partir do ponto de declaração para var, continua para baixo até o final do arquivo (unidade de tradução).

O bloco da função main () é um escopo diferente; é um escopo aninhado para o escopo global. Para acessar uma entidade de escopo global, a partir de um escopo diferente, o identificador é usado diretamente ou precedido pelo operador de resolução de escopo, :: .

Nota: A entidade, main (), também é declarada no escopo global.

Escopo do Bloco

Cada instrução if, while, do, for ou switch pode definir um bloco. Essa declaração é uma declaração composta. O nome de uma variável declarada em um bloco tem o escopo de um bloco. Seu escopo começa em seu ponto de declaração e termina no final de seu bloco. O programa curto a seguir ilustra isso para a variável, ident:

#incluir
usando namespace std;
int main ()

if (1 == 1)

/ * algumas declarações * /
int ident = 5;
cout</ * algumas declarações * /

return 0;

Uma variável, como ident, declarada no escopo do bloco é uma variável local.

Uma variável declarada fora do escopo do bloco e acima dela pode ser vista no cabeçalho do bloco (e.g., condição para if-block) e também dentro do bloco. O programa curto a seguir ilustra isso para a variável, identif:

#incluir
usando namespace std;
int main ()

identif int = 8;
if (identif == 8)

cout<
return 0;

A saída é 8. Existem dois escopos de bloco aqui: o bloco para a função main () e a instrução if-composta aninhada. O bloco aninhado é o escopo potencial do bloco de função main ().

Uma declaração introduzida em um escopo de bloco não pode ser vista fora do bloco. O programa curto a seguir, que não compila, ilustra isso com a variável, variab:

#incluir
usando namespace std;
int main ()

if (1 == 1)

int variab = 15;

cout<return 0;

O compilador produz uma mensagem de erro para variab.

Uma entidade introduzida, declarada no cabeçalho de uma função composta, não pode ser vista fora (abaixo) da instrução composta. O seguinte código for-loop não será compilado, resultando em uma mensagem de erro:

#incluir
usando namespace std;
int main ()

para (int i = 0; i<4; ++i)

cout<
cout<return 0;

A variável de iteração, i, é vista dentro do bloco for-loop, mas não fora do bloco for-loop.

Escopo da Função

Um parâmetro de função é visto no bloco de função. Uma entidade declarada em um bloco de função é vista do ponto de declaração até o final do bloco de função. O programa curto a seguir ilustra isso:

#incluir
#incluir
usando namespace std;
string fn (string str)

char stri [] = "bananas";
/ * outras declarações * /
string totalStr = str + stri;
return totalStr;

int main ()

string totStr = fn ("comendo");
cout<return 0;

O resultado é:
comendo bananas

Nota: Uma entidade declarada fora da função (acima dela) pode ser vista na lista de parâmetros da função e também no bloco de funções.

Rótulo

O escopo de um rótulo é a função na qual ele aparece. O código a seguir ilustra isso:

#incluir
usando namespace std;
void fn ()

goto labl;
/ * outras declarações * /
labl: int inte = 2;
cout<
int main ()

fn ();
return 0;

A saída é 2.

Escopo de Enumeração

Enumeração sem escopo
Considere o seguinte bloco if:

if (1 == 1)

enum a, b, c = b + 2;
cout<

A saída é 0 1 3.

A primeira linha do bloco é uma enumeração, a, b e c são seus enumeradores. O escopo de um enumerador começa do ponto de declaração até o final do bloco envolvente da enumeração.

A instrução a seguir não será compilada porque o ponto de declaração de c é após o de a:

enum a = c + 2, b, c;

O seguinte segmento de código não será compilado porque os enumeradores são acessados ​​após o bloco delimitador da enumeração:

if (1 == 1)

enum a, b, c = b + 2;

cout<A enumeração acima é descrita como uma enumeração sem escopo e seus enumeradores são descritos como enumeradores sem escopo. Isso ocorre porque ele começa apenas com a palavra reservada, enum. Enumerações que começam com classe enum ou estrutura enum são descritas como enumerações com escopo. Seus enumeradores são descritos como enumeradores com escopo.

Enumeração com Escopo
A seguinte declaração está correta:

enum class nam a, b, c = b + 2;

Este é um exemplo de enumeração com escopo. O nome da classe é nam. Aqui, o escopo do enumerador começa do ponto de declaração até o final da definição de enumeração, e não o final do bloco delimitador para a enumeração. O código a seguir não será compilado:

if (1 == 1)

enum class nam a, b, c = b + 2;
cout<

Escopo da classe

Com o escopo normal, a região declarativa começa de um ponto, depois continua e para em um ponto diferente. O escopo existe em uma região contínua. Com a classe, o escopo de uma entidade pode estar em diferentes regiões que não estão unidas. As regras para blocos aninhados ainda se aplicam. O programa a seguir ilustra isso:

#incluir
usando namespace std;
// Classe base
classe Cla

privado:
int memP = 5;
protegido:
int memPro = 9;
público:
void fn ()

cout<
;
//Classe derivada
classe DerCla: public Cla

público:
int derMem = memPro;
;
int main ()

Cla obj;
obj.fn ();
DerCla derObj;
cout<return 0;

O resultado é:
5
9

Na classe Cla, a variável memP, é vista no ponto de declaração. Depois disso, a pequena parte de "protegido" é ignorada e vista novamente no bloco de funções do membro da classe. A classe derivada é ignorada e vista novamente no escopo da função main () (bloco).

Na classe Cla, a variável memPro, é vista no ponto de declaração. A parte da função pública fn () é ignorada e vista no bloco de descrição da classe derivada. É visto novamente na função main ().

Operador de resolução de escopo
O operador de resolução de escopo em C ++ é :: . É usado para acessar um membro estático da classe. O programa a seguir ilustra isso:

#incluir
usando namespace std;
classe Cla

público:
estático int const mem = 5;
público:
static void fn ()

cout<
;
int main ()

cout<Cla :: fn ();
return 0;

O resultado é:
5
5

Os membros estáticos são vistos no bloco de funções main (), acessado usando o operador de resolução de escopo.

Âmbito do parâmetro do modelo

O escopo normal de um nome de parâmetro de modelo começa do ponto de declaração até o final de seu bloco, como no código a seguir:

modelo Idade Estrutural

T John = 11;
U Peter = 12.3;
T Mary = 13;
U Joy = 14.6;
;

U e T são vistos dentro do bloco.

Para um protótipo de função de modelo, o escopo começa do ponto de declaração até o final da lista de parâmetros de função, como na seguinte instrução:

modelo void func (T no, U cha, const char * str);

No entanto, quando se trata da descrição da classe (definição), o escopo também pode ser de partes diferentes, como no código a seguir:

#incluir
usando namespace std;
modelo classe TheCla

público:
T num;
estático U ch;
void func (U cha, const char * str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

static void fun (U ch)

if (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

TheCla obj;
obj.num = 12;
obj.func ('$', "500");
return 0;

Esconder o Nome

Um exemplo de ocultação de nome ocorre quando o nome do mesmo tipo de objeto é declarado novamente em um bloco aninhado. O programa a seguir ilustra isso:

#incluir
usando namespace std;
void fn ()

int var = 3;
if (1 == 1)

int var = 4;
cout<
cout<
int main ()

fn ();
return 0;

O resultado é:
4
3

É porque var no bloco aninhado escondeu var no bloco externo.

Possibilidade de repetição de declaração no mesmo escopo

O ponto da declaração é onde o nome é introduzido (pela primeira vez) em seu escopo.

Protótipo de Função
Entidades diferentes, mesmo de tipos diferentes, normalmente não podem ser declaradas no mesmo escopo. No entanto, um protótipo de função pode ser declarado mais de uma vez no mesmo escopo. O programa a seguir com dois protótipos de função e definição de função correspondente ilustra isso:

#incluir
usando namespace std;
void fn (int num);
void fn (int num);
void fn (int num)

cout<
int main ()

fn (5);
return 0;

O programa funciona.

Funções sobrecarregadas
Funções sobrecarregadas são funções com o mesmo nome, mas assinaturas de função diferentes. Como outra exceção, funções sobrecarregadas com o mesmo nome podem ser definidas no mesmo escopo. O programa a seguir ilustra isso:

#incluir
usando namespace std;
void fn (int num)

cout<
void fn (float no)

cout<
int main ()

fn (5);
float flt = 8.7;
fn (flt);
return 0;

O resultado é:
5
8.7

As funções sobrecarregadas foram definidas no âmbito global.

Escopo do namespace

O escopo do namespace merece seu próprio artigo. O referido artigo foi escrito para este site, linuxhint.com. Basta digitar as palavras de pesquisa “Namespace Scope” na caixa de pesquisa deste site (página) e clicar em OK, e você obterá o artigo.

Escopo em porções diferentes

A classe não é o único esquema em que o escopo pode estar em porções diferentes. Especificador de amigo, certos usos do especificador de tipo elaborado e diretivas de uso são outros esquemas onde o escopo está em lugares diferentes - para detalhes, veja mais tarde.

Conclusão

Um escopo é uma região declarativa. Uma região declarativa é a maior parte de um texto de programa em que o nome de uma entidade é válido. Ele pode ser dividido em mais de uma parte de acordo com certos esquemas de programação, como blocos aninhados. As partes que não têm o ponto de declaração formam o escopo potencial. O escopo potencial pode ou não ter a declaração.

Como baixar e jogar Sid Meier's Civilization VI no Linux
Introdução ao jogo Civilization 6 é uma versão moderna do conceito clássico introduzido na série de jogos Age of Empires. A ideia era bastante simples...
Como instalar e jogar Doom no Linux
Introdução ao Doom A série Doom teve origem nos anos 90 após o lançamento do Doom original. Foi um sucesso instantâneo e, a partir desse momento, a sé...
Vulkan para usuários de Linux
A cada nova geração de placas gráficas, vemos os desenvolvedores de jogos ultrapassarem os limites da fidelidade gráfica e se aproximarem mais do foto...