Fundamentos de Funções e Programação Genérica em C++

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;
}

Tags: cpp templates functions programming-logic memory-management

Publicado em 6-11 21:35 por Thomas