Deixe-me tentar responder a isso também.
Os ponteiros são semelhantes às referências. Em outras palavras, não são cópias, mas uma maneira de se referir ao valor original.
Antes de qualquer coisa, um lugar em que você normalmente precisará usar muito os ponteiros é quando está lidando com hardware incorporado . Talvez você precise alternar o estado de um pino de E / S digital. Talvez você esteja processando uma interrupção e precise armazenar um valor em um local específico. Você entendeu a foto. No entanto, se você não está lidando com hardware diretamente e está apenas se perguntando sobre quais tipos usar, continue a ler.
Por que usar ponteiros em vez de variáveis normais? A resposta fica mais clara quando você lida com tipos complexos, como classes, estruturas e matrizes. Se você usar uma variável normal, poderá acabar fazendo uma cópia (os compiladores são inteligentes o suficiente para evitar isso em algumas situações e o C ++ 11 também ajuda, mas ficaremos longe dessa discussão por enquanto).
Agora, o que acontece se você deseja modificar o valor original? Você poderia usar algo como isto:
MyType a; //let's ignore what MyType actually is right now.
a = modify(a);
Isso funcionará bem e, se você não souber exatamente por que está usando ponteiros, não deverá usá-los. Cuidado com o motivo "provavelmente são mais rápidos". Execute seus próprios testes e, se eles realmente forem mais rápidos, use-os.
No entanto, digamos que você esteja resolvendo um problema em que precisa alocar memória. Ao alocar memória, é necessário desalocá-la. A alocação de memória pode ou não ser bem-sucedida. É aqui que os ponteiros se tornam úteis - permitem testar a existência do objeto que você alocou e permitem acessar o objeto para o qual a memória foi alocada, retirando a referência do ponteiro.
MyType *p = NULL; //empty pointer
if(p)
{
//we never reach here, because the pointer points to nothing
}
//now, let's allocate some memory
p = new MyType[50000];
if(p) //if the memory was allocated, this test will pass
{
//we can do something with our allocated array
for(size_t i=0; i!=50000; i++)
{
MyType &v = *(p+i); //get a reference to the ith object
//do something with it
//...
}
delete[] p; //we're done. de-allocate the memory
}
Essa é a chave para o uso de ponteiros - as referências assumem que o elemento que você está referenciando já existe . Um ponteiro não.
A outra razão pela qual você usaria ponteiros (ou pelo menos acabaria tendo que lidar com eles) é porque eles são um tipo de dados que existia antes das referências. Portanto, se você acabar usando bibliotecas para fazer as coisas que você sabe que são melhores, você descobrirá que muitas dessas bibliotecas usam ponteiros em todo o lugar, simplesmente por quanto tempo elas estão por aí (muitas deles foram escritos antes de C ++).
Se você não usou nenhuma biblioteca, pode projetar seu código de maneira a evitar os ponteiros, mas, como os ponteiros são um dos tipos básicos da linguagem, quanto mais rápido você se sentir confortável com eles, mais portátil, suas habilidades em C ++ seriam.
Do ponto de vista da capacidade de manutenção, devo mencionar também que, quando você usa ponteiros, é necessário testar sua validade e lidar com o caso quando eles não são válidos, ou apenas assumir que eles são válidos e aceitar o fato de que seu programa falhará ou pior quando essa suposição for quebrada. Em outras palavras, sua escolha com ponteiros é introduzir complexidade de código ou mais esforços de manutenção quando algo quebra e você está tentando rastrear um bug que pertença a toda uma classe de erros que os ponteiros introduzem, como corrupção de memória.
Portanto, se você controla todo o seu código, fique longe de ponteiros e use referências, mantendo-os constantes quando puder. Isso forçará você a pensar sobre o tempo de vida de seus objetos e acabará mantendo seu código mais fácil de entender.
Lembre-se desta diferença: uma referência é essencialmente um ponteiro válido. Um ponteiro nem sempre é válido.
Estou dizendo que é impossível criar uma referência inválida? Não. É totalmente possível, porque o C ++ permite fazer quase qualquer coisa. É apenas mais difícil de fazer sem querer e você ficará surpreso com a quantidade de bugs não intencionais :)