Ponteiros e Referências
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 13 de 104.
Agora que você entende a memória stack e heap, vamos explorar as ferramentas que permitem trabalhar diretamente com locais de memória: ponteiros e referências.
Um ponteiro armazena o endereço de memória de outra variável. Você o declara com * e obtém um endereço usando &.
int value = 42;
int* ptr = &value; // ptr contém o endereço de value
std::cout << ptr; // Imprime o endereço de memória
std::cout << *ptr; // Desreferência: imprime 42Uma referência é um apelido para uma variável existente. Uma vez vinculada, ela sempre se refere a essa variável. Você a declara com &.
int value = 42;
int& ref = value; // ref é um alias para value
ref = 100; // Altera value para 100
std::cout << value; // Imprime 100Principais diferenças:
| Ponteiros | Referências |
|---|---|
| Podem ser nulos | Devem ser inicializadas |
| Podem ser reatribuídos | Não podem ser vinculadas novamente |
Use * para acessar o valor | Acessam o valor diretamente |
| Podem apontar para nada | Sempre válidas |
Ambos são essenciais para passar objetos para funções de maneira eficiente sem realizar cópias, e para trabalhar com memória alocada no heap. Referências são mais seguras e simples, enquanto ponteiros oferecem mais flexibilidade quando você precisa reatribuir ou verificar se é nulo.
Desafio
FácilVamos construir um sistema simples de manipulação de valores que demonstra como ponteiros e referências funcionam de forma diferente ao modificar dados.
Você criará dois arquivos para organizar seu código:
ValueOps.h: Defina três funções que modificam valores inteiros de diferentes maneiras:doubleByPointer(int* ptr)— recebe um ponteiro e dobra o valor para o qual ele apontatripleByReference(int& ref)— recebe uma referência e triplica o valorswapValues(int* a, int* b)— recebe dois ponteiros e troca os valores para os quais eles apontam
main.cpp: Leia dois inteiros da entrada e, em seguida, demonstre tanto ponteiros quanto referências:- Imprima os valores originais:
"Original: <first> <second>" - Use
doubleByPointerno primeiro valor e, em seguida, imprima:"After double: <first>" - Use
tripleByReferenceno segundo valor e, em seguida, imprima:"After triple: <second>" - Use
swapValuespara trocar ambos os valores e, em seguida, imprima:"After swap: <first> <second>"
- Imprima os valores originais:
Ao chamar funções com ponteiros, lembre-se de usar o operador de endereço (&) para passar o endereço da variável. As referências funcionam de forma mais natural — basta passar a variável diretamente.
Inclua seu arquivo de cabeçalho no main.cpp usando #include "ValueOps.h".
Folha de consulta
Um ponteiro armazena o endereço de memória de outra variável. Declare-o com * e obtenha um endereço usando &:
int value = 42;
int* ptr = &value; // ptr contém o endereço de value
std::cout << ptr; // Imprime o endereço de memória
std::cout << *ptr; // Desreferência: imprime 42Uma referência é um apelido para uma variável existente. Declare-a com &:
int value = 42;
int& ref = value; // ref é um apelido para value
ref = 100; // Altera value para 100
std::cout << value; // Imprime 100Principais diferenças:
| Ponteiros | Referências |
|---|---|
| Pode ser nulo | Deve ser inicializada |
| Pode ser reatribuído | Não pode ser vinculada a outra variável |
Use * para acessar o valor | Acessa o valor diretamente |
| Pode apontar para nada | Sempre válida |
Ao chamar funções com ponteiros, use o operador de endereço (&) para passar o endereço da variável. Referências funcionam diretamente — basta passar a variável.
Experimente você mesmo
#include <iostream>
#include "ValueOps.h"
using namespace std;
int main() {
// Leia dois inteiros da entrada
int first, second;
cin >> first;
cin >> second;
// Imprima os valores originais
cout << "Original: " << first << " " << second << endl;
// TODO: Use doubleByPointer no primeiro valor (passe o endereço usando &)
// TODO: Imprima após o dobro
// TODO: Use tripleByReference no segundo valor (passe a variável diretamente)
// TODO: Imprima após o triplo
// TODO: Use swapValues para trocar ambos os valores (passe os endereços usando &)
// TODO: Imprima após a troca
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de OOP
Arquivos ExternosBuild e Compilação em C++Arquivos Header e SourceNamespaces e EscopoIntrodução a OOP em C++Classes vs ObjetosO Ponteiro 'this'Métodos (Funções Membro)Atributos (Membros de Dados)Básico de Ctors e DtorsRecapitulação - Calculadora Simples4Propriedades de Classe
Membros de Instância vs EstáticosGetters e SettersFunções de Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRecapitulação - Gerenciador de Conta Bancária7Herança
Herança BásicaNíveis de Acesso na HerançaOrdem de Chamada de Ctor e DtorSobrescrita de MétodosFunções Virtuais e VTableHerança MúltiplaHerança VirtualRecapitulação - Hierarquia de Funcionários2Gerenciamento de Memória
Memória Stack vs HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Smart Pointers em C++RAII em C++Recapitulação - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de Acesso em C++Especificadores de Acesso em DetalhesOcultação de InformaçãoStruct vs ClassClasses Aninhadas e InternasRecapitulação - Sistema de Registros de Alunos8Polimorfismo
Polimorfismo de Compilação vs Tempo de ExecuçãoSobrecarga de FunçõesFunções Virtuais RevisitadasFunções Virtuais PurasClasses AbstratasDesign de Interfaces em C++Dynamic Casting e RTTIRecapitulação - Calculadora de Formas3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentaçãoListas de Inicialização do ConstrutorConstrutores DelegadosMergulho Profundo em DestrutoresRegra dos Três / Cinco / ZeroRecapitulação - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de StreamSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçãoTemplates de ClasseEspecialização de TemplatesTemplates VariádicosFundamentos de SFINAE e Type TraitsRecapitulação - Container Genérico