Sobrecarga de Funções
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 57 de 104.
Sobrecarga de função permite que você defina múltiplas funções com o mesmo nome, mas com diferentes listas de parâmetros. O compilador seleciona a versão correta com base nos argumentos que você passa. Esta é uma forma fundamental de polimorfismo em tempo de compilação.
Para que a sobrecarga funcione, as funções devem diferir em sua assinatura - o número de parâmetros, seus tipos, ou ambos:
class Calculator {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
};
Calculator calc;
calc.add(5, 3); // Chama add(int, int)
calc.add(2.5, 3.7); // Chama add(double, double)
calc.add(1, 2, 3); // Chama add(int, int, int)O compilador examina cada chamada e a associa à sobrecarga apropriada. Isso acontece inteiramente em tempo de compilação, portanto não há sobrecarga em tempo de execução.
Importante: O tipo de retorno por si só não distingue funções sobrecarregadas. O seguinte causaria um erro de compilação:
int getValue();
double getValue(); // Erro: não é possível sobrecarregar apenas pelo tipo de retornoA sobrecarga de funções torna seu código mais intuitivo. Em vez de criar nomes separados como addInts, addDoubles e addThreeInts, você usa um único nome significativo e deixa o compilador lidar com o resto.
Desafio
FácilVamos construir uma classe formatadora de mensagens que demonstra o poder da sobrecarga de funções. Você criará uma classe Formatter com múltiplos métodos format() que lidam com diferentes tipos de entrada, permitindo que o compilador escolha a versão correta com base no que você passar.
Você organizará seu código em dois arquivos:
Formatter.h: Defina uma classeFormattercom métodosformat()sobrecarregados que lidam com diferentes cenários:- Um método que recebe uma única
std::stringe imprime:Message: <text> - Um método que recebe uma
std::stringe um nível de prioridadeint, imprimindo:[Priority <priority>] <text> - Um método que recebe uma
std::stringe um timestampdouble, imprimindo:[<timestamp>s] <text> - Um método que recebe três parâmetros
std::string(remetente, destinatário, mensagem) e imprime:From <sender> to <receiver>: <message>
format()— o compilador selecionará o correto com base nos argumentos.- Um método que recebe uma única
main.cpp: Leia quatro entradas (cada uma em uma linha separada):- Um texto de mensagem simples
- Um nível de prioridade (inteiro)
- Um timestamp (double)
- Um nome de remetente
Crie um objeto
Formattere demonstre todos os quatro métodos sobrecarregados:- Chame
format()apenas com o texto da mensagem - Chame
format()com o texto da mensagem e a prioridade - Chame
format()com o texto da mensagem e o timestamp - Chame
format()com o remetente, "Admin" como o destinatário, e o texto da mensagem
Por exemplo, com as entradas System ready, 3, 12.5, e Server:
Message: System ready
[Priority 3] System ready
[12.5s] System ready
From Server to Admin: System readyObserve como você chama o mesmo nome de método format() quatro vezes, mas cada chamada invoca uma versão diferente com base nos tipos e na contagem de argumentos. Isso é o polimorfismo de tempo de compilação em ação — o compilador determina qual sobrecarga usar antes mesmo do programa ser executado.
Folha de consulta
A sobrecarga de funções permite que você defina múltiplas funções com o mesmo nome, mas com listas de parâmetros diferentes. O compilador seleciona a versão correta com base nos argumentos passados em tempo de compilação.
As funções devem diferir em sua assinatura - o número de parâmetros, seus tipos, ou ambos:
class Calculator {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
};
Calculator calc;
calc.add(5, 3); // Chama add(int, int)
calc.add(2.5, 3.7); // Chama add(double, double)
calc.add(1, 2, 3); // Chama add(int, int, int)Importante: O tipo de retorno sozinho não pode distinguir funções sobrecarregadas:
int getValue();
double getValue(); // Erro: não é possível sobrecarregar apenas pelo tipo de retornoA sobrecarga de funções é uma forma de polimorfismo em tempo de compilação sem sobrecarga (overhead) em tempo de execução.
Experimente você mesmo
#include <iostream>
#include <string>
#include "Formatter.h"
using namespace std;
int main() {
// Ler entradas
string message;
getline(cin, message);
int priority;
cin >> priority;
double timestamp;
cin >> timestamp;
cin.ignore();
string sender;
getline(cin, sender);
// TODO: Criar um objeto Formatter
// TODO: Chamar format() apenas com o texto da mensagem
// TODO: Chamar format() com o texto da mensagem e a prioridade
// TODO: Chamar format() com o texto da mensagem e o timestamp
// TODO: Chamar format() com o remetente, "Admin" como destinatário e o texto da mensagem
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