O que é um identificador em C ++?

97

Disseram-me que um identificador é uma espécie de ponteiro, mas não, e que permite manter uma referência a um objeto, em vez do próprio objeto. O que é uma explicação mais elaborada?

Xenoprimato
fonte
2
Observe o padrão Chain of Responsibility, você aprenderá que um "Handle" é basicamente um nó, e que um "Handler" é um pequeno conjunto deles. A "mágica" vem da recursão

Respostas:

100

Um identificador pode ser qualquer coisa, desde um índice inteiro a um ponteiro para um recurso no espaço do kernel. A ideia é que eles forneçam uma abstração de um recurso, então você não precisa saber muito sobre o recurso em si para usá-lo.

Por exemplo, o HWND na API Win32 é um identificador para uma janela. Por si só, é inútil: você não pode obter nenhuma informação dele. Mas passe-o para as funções de API corretas e você poderá executar uma variedade de truques diferentes com ele. Internamente, você pode pensar no HWND apenas como um índice na tabela de janelas da GUI (que pode não ser necessariamente como ele é implementado, mas faz a mágica fazer sentido).

EDIT: Não tenho 100% de certeza do que você estava perguntando especificamente em sua pergunta. Isso se refere principalmente a C / C ++ puro.

Matthew Iselin
fonte
13
Um identificador pode ser útil para salvar estados (entre outros). Se vc tiver dados em uma estrutura como um std :: vector. Seu objeto pode estar em locais de memória diferentes em momentos diferentes durante a execução de um programa, o que significa que seu ponteiro para essa memória mudará os valores. Com um identificador, ele nunca muda, sempre faz referência ao seu objeto. Imagine salvar o estado de um programa (como em um jogo) - você não salvaria a localização de um ponteiro para dados e depois importaria os dados novamente e tentaria obter esse endereço na memória. No entanto, você pode salvar um identificador com seus dados e importar os dados e o identificador.
SinisterRainbow
É possível converter um HANDLE em um equivalente no Linux? Tenho que migrar um programa que usa HANDLE do Windows para o Linux.
Cornel Verster
1
Essa é a resposta correta, que eles podem ser qualquer coisa e que o código que os usa define o tipo de identificador. Tentei fazer uma versão mais concisa de minha própria resposta semelhante, não pude evitar, para a posteridade. @CornelVerster - Eles são os mesmos no Linux. Quer dizer, não trata o sistema operacional, mas o conceito. Então, depende do identificador quanto a sua migração, ou mesmo a necessidade de migração.
dyasta
@Matthew Iselin: em qualquer documentação de API, eles definem que algo é um manipulador, então devemos saber como passá-los para funções, caso contrário, como podemos saber o que é um manipulador na documentação de API
Amin Khormaei
51

Um identificador é um ponteiro ou índice sem tipo visível anexado a ele. Normalmente você vê algo como:

 typedef void* HANDLE;
 HANDLE myHandleToSomething = CreateSomething();

Portanto, em seu código, você apenas passa HANDLE como um valor opaco.

No código que usa o objeto, ele lança o ponteiro para um tipo de estrutura real e o usa:

 int doSomething(HANDLE s, int a, int b) {
     Something* something = reinterpret_cast<Something*>(s);
     return something->doit(a, b);
 }

Ou ele o usa como um índice para uma matriz / vetor:

 int doSomething(HANDLE s, int a, int b) {
     int index = (int)s;
     try {
         Something& something = vecSomething[index];
         return something.doit(a, b);
     } catch (boundscheck& e) {
         throw SomethingException(INVALID_HANDLE);
     }
 }
jmucchiello
fonte
29

Um identificador é uma espécie de ponteiro, pois normalmente é uma forma de referenciar alguma entidade.

Seria mais preciso dizer que um ponteiro é um tipo de identificador, mas nem todos os identificadores são ponteiros.

Por exemplo, um identificador também pode ser algum índice em uma tabela na memória, que corresponde a uma entrada que contém um ponteiro para algum objeto.

O principal é que quando você tem um "identificador", você não sabe nem se importa como esse identificador realmente acaba identificando o que ele identifica, tudo o que você precisa saber é que ele identifica.

Também deveria ser óbvio que não há uma resposta única para "o que exatamente é uma alça", porque alças para coisas diferentes, mesmo no mesmo sistema, podem ser implementadas de maneiras diferentes "por baixo do capô". Mas você não precisa se preocupar com essas diferenças.

Deltics
fonte
6

Em C ++ / CLI, um identificador é um ponteiro para um objeto localizado na pilha de GC. A criação de um objeto no heap C ++ (não gerenciado) é obtida usando newe o resultado de uma newexpressão é um ponteiro "normal". Um objeto gerenciado é alocado no heap do GC (gerenciado) com uma gcnewexpressão. O resultado será uma alça. Você não pode fazer aritmética de ponteiro em alças. Você não libera alças. O CG cuidará deles. Além disso, o GC está livre para realocar objetos no heap gerenciado e atualizar as alças para apontar para os novos locais enquanto o programa está em execução.

Mehrdad Afshari
fonte
5

Isso aparece no contexto do idioma Handle-Body-Idiom , também chamado de idioma Pimpl. Ele permite manter a ABI (interface binária) de uma biblioteca igual, mantendo os dados reais em outro objeto de classe, que é meramente referenciado por um ponteiro mantido em um objeto "manipulador", consistindo de funções que delegam a essa classe " Corpo".

Também é útil para permitir tempo constante e troca segura de exceção de dois objetos. Para isso, basta trocar o ponteiro que aponta para o objeto do corpo.

Johannes Schaub - litb
fonte
2

Uma alça é o que você quiser.

Um identificador pode ser um inteiro sem sinal usado em alguma tabela de pesquisa.

Um identificador pode ser um ponteiro para ou para um conjunto maior de dados.

Depende de como o código que usa o identificador se comporta. Isso determina o tipo de alça.

O motivo pelo qual o termo ' identificador ' é usado é o que é importante. Isso os indica como uma identificação ou tipo de objeto de acesso. Ou seja, para o programador, eles representam uma 'chave' ou acesso a algo.

dyasta
fonte
2

HANDLE hnd; é o mesmo que void * ptr;

HANDLE é um typedef definido no arquivo winnt.h no Visual Studio (Windows):

typedef void *HANDLE;

Leia mais sobre HANDLE

Kulamani
fonte
1
Isso se aplica apenas ao Windows e apenas um dos muitos tipos de alças usados ​​na arquitetura do Windows. No entanto, isso é o que seria conhecido como um 'identificador de nível de aplicativo normal do Windows'.
dyasta