C++: Sobrecarga de Funções e Argumentos Padrão
Última atualização: 2026-08-26
Às vezes você precisa de uma função que pode lidar com tipos diferentes ou números diferentes de parâmetros.
Por exemplo, uma função
C++ fornece dois recursos para isso — sobrecarga de funções e argumentos padrão.
1. Sobrecarga de Funções
(1) 1.1 O que é Sobrecarga de Funções?
Sobrecarga de funções permite que você defina múltiplas funções com o mesmo nome, mas com listas de parâmetros diferentes.
| Assinatura da Função | Significado |
|---|---|
print(int x) |
Imprimir um inteiro |
print(double x) |
Imprimir um ponto flutuante |
print(const std::string& x) |
Imprimir uma string |
Quando chamadas, o compilador seleciona automaticamente a função correta com base nos tipos dos argumentos.
▶ Exemplo 1: Sobrecarga de Funções (Dificuldade ⭐)
#include <iostream>
#include <string>
void print(int x) {
std::cout << "Integer: " << x << std::endl;
}
void print(double x) {
std::cout << "Float: " << x << std::endl;
}
void print(const std::string& x) {
std::cout << "String: " << x << std::endl;
}
int main() {
print(5); // Chama print(int)
print(3.14); // Chama print(double)
print("Hello"); // Chama print(const char*)
return 0;
}
Saída:
Integer: 5
Float: 3.14
String: Hello
⚠️ Ponto-chave: A condição para sobrecarga de funções é que a lista de parâmetros deve diferir (tipos diferentes, contagem diferente, ou ordem diferente). Apenas um tipo de retorno diferente não constitui sobrecarga.
2. Regras para Sobrecarga de Funções
(1) 2.1 O Que Conta como "Lista de Parâmetros Diferente"?
| Diferença | Exemplo |
|---|---|
| Tipos diferentes | void foo(int x) vs void foo(double x) |
| Contagem diferente | void foo(int x) vs void foo(int x, int y) |
| Ordem diferente | void foo(int x, double y) vs void foo(double x, int y) |
(2) 2.2 O Que NÃO Conta como Sobrecarga?
| Situação | Exemplo | Resultado |
|---|---|---|
| Apenas tipo de retorno difere | int foo() vs double foo() |
❌ Erro de compilação: redefinição |
| Apenas nomes de parâmetros diferem | void foo(int x) vs void foo(int y) |
❌ Erro de compilação: redefinição |
3. Argumentos Padrão
(1) 3.1 Uso Básico
Argumentos padrão permitem que você omite certos argumentos ao chamar uma função — o compilador usará automaticamente os valores padrão.
#include <iostream>
void print(int x, int y = 10) {
std::cout << "x = " << x << ", y = " << y << std::endl;
}
int main() {
print(5); // Passa apenas um argumento, y usa valor padrão 10
print(5, 20); // Passa dois argumentos, y é alterado para 20
return 0;
}
(2) 3.2 Regras para Argumentos Padrão
- Valores padrão só podem ser definidos da direita para esquerda
void foo(int a, int b = 10, int c = 20); // ✅ Correto
void bar(int a = 5, int b, int c); // ❌ Erro: a tem padrão mas b não
- Argumentos padrão só podem ser especificados uma vez — no protótipo ou na definição
int add(int a, int b = 10); // Especifica padrão no protótipo
int main() {
std::cout << add(5) << std::endl;
return 0;
}
int add(int a, int b) { // ✅ Não escreva o padrão novamente na definição
return a + b;
}
4. Sobrecarga de Funções + Argumentos Padrão
Sobrecarga de funções e argumentos padrão podem ser usados juntos para tornar as funções mais flexíveis.
▶ Exemplo 2: Imprimir Array com Delimitador (Dificuldade ⭐⭐)
#include <iostream>
#include <string>
void printArray(int arr, int length) {
printArray(arr, length, ", ");
}
void printArray(int arr, int length, const std::string& delimiter) {
for (int i = 0; i < length; i++) {
std::cout << arr[i];
if (i < length - 1) {
std::cout << delimiter;
}
}
std::cout << std::endl;
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
printArray(arr, 5); // Usa delimitador padrão ", "
printArray(arr, 5, " - "); // Usa delimitador personalizado " - "
return 0;
}
Saída:
1, 2, 3, 4, 5
1 - 2 - 3 - 4 - 5
5. Prática: Função de Log Simples
▶ Exemplo 3: Função de Impressão com Níveis de Log (Dificuldade ⭐⭐)
#include <iostream>
#include <string>
#include <ctime>
enum LogLevel {
INFO,
WARNING,
ERROR
};
std::string getCurrentTime() {
std::time_t now = std::time(nullptr);
std::tm* tm = std::localtime(&now);
char buffer[80];
std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm);
return std::string(buffer);
}
void log(const std::string& message) {
log(message, INFO);
}
void log(const std::string& message, LogLevel level) {
std::string levelStr;
if (level == INFO) {
levelStr = "INFO";
} else if (level == WARNING) {
levelStr = "WARNING";
} else {
levelStr = "ERROR";
}
std::cout << "[" << getCurrentTime() << "] [" << levelStr << "] " << message << std::endl;
}
int main() {
log("Program started");
log("Insufficient memory", WARNING);
log("File open failed", ERROR);
return 0;
}
Saída:
[] []
Saída (exemplo):
[2026-06-28 22:30:00] [INFO] Program started
[2026-06-28 22:30:01] [WARNING] Insufficient memory
[2026-06-28 22:30:02] [ERROR] File open failed
6. Erros Comuns
(1) 6.1 Ambiguidade na Sobrecarga de Funções
Exemplo de erro:
#include <iostream>
void foo(int x) {
std::cout << "foo(int)" << std::endl;
}
void foo(double x) {
std::cout << "foo(double)" << std::endl;
}
int main() {
foo(5); // ✅ Chama foo(int)
foo(3.14); // ✅ Chama foo(double)
foo('A'); // ❌ Ambíguo: char pode converter para int ou double
return 0;
}
Mensagem de erro de compilação:
error: call to 'foo' is ambiguous
Correção: Conversão explícita de tipo:
foo(static_cast<int>('A')); // Chama foo(int)
foo(static_cast<double>('A')); // Chama foo(double)
(2) 6.2 Argumentos Padrão Causando Ambiguidade de Sobrecarga
Exemplo de erro:
#include <iostream>
void foo(int x) {
std::cout << "foo(int)" << std::endl;
}
void foo(int x, int y = 10) {
std::cout << "foo(int, int)" << std::endl;
}
int main() {
foo(5); // ❌ Ambíguo: pode chamar foo(int) ou foo(int, int) com padrão
return 0;
}
Correção: Remova uma das sobrecargas, ou mude o tipo de um parâmetro.
❓ Perguntas Frequentes
P: Qual a diferença entre sobrecarga de funções e funções estilo C? R: C não suporta sobrecarga de funções porque as regras de name mangling do compilador C são simples (basicamente apenas o nome da função). Compiladores C++ realizam name mangling, codificando informações de tipo de parâmetro no nome da função, então funções de mesmo nome podem coexistir.
P: Argumentos padrão podem ser variáveis? R: Sim, mas devem ser variáveis globais ou estáticas (coberto mais tarde).
CPPint defaultY = 10; void foo(int x, int y = defaultY) { // Pode ser uma variável // ... }
P: Sobrecarga de funções melhora a eficiência em tempo de execução? R: Não. Sobrecarga de funções é um recurso de tempo de compilação (o compilador seleciona a função com base nos tipos dos argumentos); a eficiência em tempo de execução é a mesma de uma chamada de função normal. Ela melhora a eficiência de desenvolvimento (código é mais conciso e legível).
📖 Resumo
- Sobrecarga de funções permite definir múltiplas funções de mesmo nome com listas de parâmetros diferentes
- Argumentos padrão permitem omitir certos argumentos; o compilador preenche os valores padrão
- Argumentos padrão só podem ser definidos da direita para esquerda
- Sobrecarga de funções + argumentos padrão tornam as funções mais flexíveis
- Tenha cuidado para evitar ambiguidade de sobrecarga
📝 Exercícios
-
Básico (Dificuldade ⭐): Escreva funções sobrecarregadas
int max(int a, int b)edouble max(double a, double b)que retornem o máximo de dois inteiros e dois pontos flutuantes respectivamente. -
Intermediário (Dificuldade ⭐⭐): Escreva uma função
void drawRectangle(int width, int height, char fillChar = '*')que imprima um retângulo.
Input: drawRectangle(5, 3, '#')
Output:
#####
#####
#####
(Quando fillChar não é passado, usa o padrão *)
- Desafio (Dificuldade ⭐⭐⭐): Escreva um programa implementando uma "calculadora multi-função":
- Use sobrecarga de funções para implementar
add,subtract,multiply,dividepara tiposintedouble - Use argumentos padrão para definir "casas decimais" (padrão 2)
- Teste todas as funções em
main
- Sobrecarga de funções: mesmo nome, parâmetros diferentes (contagem ou tipos diferentes)
- Resolução de sobrecarga: compilador corresponde a melhor versão com base nos tipos dos argumentos
- Cuidado com ambiguidade ao misturar argumentos padrão e sobrecarga
- Não pode sobrecarregar apenas pelo tipo de retorno
- Sobrecarga torna o código mais intuitivo, usando um nome de função para tipos diferentes
7. 🚀 Próximo Passo
Agora que você aprendeu uso avançado de funções, a seguir vamos aprender escopo e tempo de vida (Aula 14) — entendendo onde variáveis podem ser acessadas e por quanto tempo existem, o que é chave para entender o comportamento do programa!