No desenvolvimento em C++, as funções são blocos fundamentais que permitem organizar o código em unidades lógicas e reutilizáveis. Além das funções tradicionais, o C++ oferece o poder dos templates para criar algoritmos genéricos que operam independentemente do tipo de dado.
Estrutura Básica de uma Função
Uma função é definida por um tipo de retorno, um identificador único, uma lista de parâmetros e um bloco de instruções. A sintaxe básica segue este padrão:
tipo_retorno nome_da_funcao(parametro1, parametro2, ...) {
// Bloco de código
return valor;
}
Veja um exemplo prático de uma função que calcula a potência simples:
#include <iostream>
int multiplicar(int fatorA, int fatorB) {
return fatorA * fatorB;
}
int main() {
int resultado = multiplicar(10, 5);
std::cout << "O produto é: " << resultado << std::endl;
return 0;
}
Funções sem Retorno e Parâmetros Vazios
Quando uma função executa uma tarefa sem a necessidade de devolver um valor ao chamador, utiliza-se o tipo void. Da mesma forma, se uma função não requer dados de entrada, a lista de parâmetros permanece vazia ou explicitamente marcada como void.
void exibirAlerta() {
std::cout << "Operação concluída com sucesso!" << std::endl;
}
Passagem de Parâmetros: Valor vs. Referência
Por padrão, o C++ utiliza a passagem por valor, o que significa que uma cópia dos dados é criada para uso interno da função. Alterações nessa cópia não afetam a variável original.
Para modificar a variável original ou evitar o custo de cópia de objetos grandes, utilizamos a passagem por referência, indicada pelo símbolo &.
#include <iostream>
void incrementar(int& numero) {
numero++;
}
int main() {
int contador = 5;
incrementar(contador);
std::cout << "Valor após incremento: " << contador << std::endl; // Saída: 6
return 0;
}
Referências Constantes
Para objetos complexos (como std::string ou std::vector), passar por referência é eficiente, mas pode ser perigoso se a função não deve alterar o objeto. O uso de const garante eficiência e segurança:
void processarTexto(const std::string& texto) {
// texto é acessado sem cópia, mas não pode ser modificado
std::cout << "Tamanho: " << texto.length() << std::endl;
}
Sobrecarga de Funções
O C++ permite que múltiplas funções compartilhem o mesmo nome, desde que suas assinaturas (quantidade ou tipo de parâmetros) sejam distintas. O compilador decide qual versão chamar com base nos argumentos fornecidos.
int calcular(int a, int b) { return a + b; }
double calcular(double a, double b) { return a * b; }
Templates de Função
Templates permitem escrever código que funciona com qualquer tipo de dado. Em vez de definir múltiplas sobrecargas, criamos uma estrutura genérica.
#include <iostream>
template <typename T>
T obterMaior(T v1, T v2) {
return (v1 > v2) ? v1 : v2;
}
int main() {
std::cout << obterMaior(10, 20) << std::endl; // T deduzido como int
std::cout << obterMaior(3.5, 1.2) << std::endl; // T deduzido como double
return 0;
}
Escopo e Visibilidade
A visibilidade de um nome (variável ou função) depende de onde ele foi declarado:
- Escopo Global: Declarado fora de qualquer bloco, acessível em todo o arquivo.
- Escopo Local: Declarado dantro de chaves
{}, acessível apenas naquele bloco.
Namespaces
Namespaces são utilizados para organizar o código e evitar conflitos de nomes em projetos de grande escala. A biblioteca padrão do C++ reside no namespace std.
namespace LogicaInterna {
int versao = 1;
void log() { std::cout << "Log v1"; }
}
int main() {
LogicaInterna::log(); // Acesso via operador de escopo
return 0;
}
Recursividade
Uma função é recursiva quando invoca a si mesma. É uma técnica poderosa para problemas que podem ser divididos em subproblemas idênticos, como o cálculo de fatoriais ou navegação em árvores.
int calcularFatorial(int n) {
if (n <= 1) return 1;
return n * calcularFatorial(n - 1);
}
Funções Inline
A diretiva inline sugere ao compilader que substitua a chamada da função pelo seu código real, eliminando o overhead da chamada de função. É ideal para funções extremamente curtas e frequentemente executadas.
inline int quadrado(int x) {
return x * x;
}