Implementação de Cálculos de Data com Sobrecarga de Operadores em C++

A manipulação de datas é um exemplo clássico para demonstrar o poder da Programação Orientada a Objetos em C++, especialmente o conceito de sobrecarga de operadores. Ao criar uma classe customizada, podemos realizar operações intuitivas como somar dias a uma data ou calcular a diferença entre dois períodos utilizando operadores aritméticos padrão.

Estrutura da Classe Calendairo

O cabeçalho abaixo define a interface da nossa classe, incluindo construtores, métodos auxiliares e a lista de operadores sobrecarregados.

#ifndef CALENDARIO_H
#define CALENDARIO_H

#include <iostream>

class Calendario {
public:
    // Construtor principal
    Calendario(int ano = 2000, int mes = 1, int dia = 1);

    // Métodos de utilidade
    void exibir() const;
    static int diasNoMes(int ano, int mes);

    // Operadores de comparação
    bool operator==(const Calendario& outro) const;
    bool operator!=(const Calendario& outro) const;
    bool operator<(const Calendario& outro) const;
    bool operator>(const Calendario& outro) const;
    bool operator<=(const Calendario& outro) const;
    bool operator>=(const Calendario& outro) const;

    // Operadores aritméticos
    Calendario& operator+=(int dias);
    Calendario operator+(int dias) const;
    Calendario& operator-=(int dias);
    Calendario operator-(int dias) const;

    // Diferença entre datas
    int operator-(const Calendario& outro) const;

    // Operadores de incremento/decremento
    Calendario& operator++();    // Pré-incremento
    Calendario operator++(int); // Pós-incremento
    Calendario& operator--();    // Pré-decremento
    Calendario operator--(int); // Pós-decremento

private:
    int ano_;
    int mes_;
    int dia_;
};

#endif

Implementação da Lógica

Abaixo, detalhamos a implementação dos métodos, focando na lógica de ajuste de calendário (anos bissextos e virada de meses/anos).

#include "Calendario.hpp"

int Calendario::diasNoMes(int ano, int mes) {
    static const int dias[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    if (mes == 2 && ((ano % 4 == 0 && ano % 100 != 0) || (ano % 400 == 0))) {
        return 29;
    }
    return dias[mes];
}

Calendario::Calendario(int ano, int mes, int dia) 
    : ano_(ano), mes_(mes), dia_(dia) {}

void Calendario::exibir() const {
    std::cout << ano_ << "-" << mes_ << "-" << dia_ << std::endl;
}

// Lógica de comparação
bool Calendario::operator==(const Calendario& outro) const {
    return ano_ == outro.ano_ && mes_ == outro.mes_ && dia_ == outro.dia_;
}

bool Calendario::operator!=(const Calendario& outro) const {
    return !(*this == outro);
}

bool Calendario::operator<(const Calendario& outro) const {
    if (ano_ != outro.ano_) return ano_ < outro.ano_;
    if (mes_ != outro.mes_) return mes_ < outro.mes_;
    return dia_ < outro.dia_;
}

// Operações aritméticas
Calendario& Calendario::operator+=(int dias) {
    dia_ += dias;
    while (dia_ > diasNoMes(ano_, mes_)) {
        dia_ -= diasNoMes(ano_, mes_);
        mes_++;
        if (mes_ > 12) {
            ano_++;
            mes_ = 1;
        }
    }
    return *this;
}

Calendario Calendario::operator+(int dias) const {
    Calendario resultado = *this;
    resultado += dias;
    return resultado;
}

Calendario& Calendario::operator-=(int dias) {
    dia_ -= dias;
    while (dia_ <= 0) {
        mes_--;
        if (mes_ < 1) {
            ano_--;
            mes_ = 12;
        }
        dia_ += diasNoMes(ano_, mes_);
    }
    return *this;
}

// Diferença entre duas datas em dias
int Calendario::operator-(const Calendario& outro) const {
    Calendario dataMenor = *this < outro ? *this : outro;
    Calendario dataMaior = *this < outro ? outro : *this;
    
    int totalDias = 0;
    while (dataMenor != dataMaior) {
        ++dataMenor;
        totalDias++;
    }
    
    return *this < outro ? -totalDias : totalDias;
}

// Incrementos
Calendario& Calendario::operator++() {
    *this += 1;
    return *this;
}

Calendario Calendario::operator++(int) {
    Calendario copia = *this;
    ++(*this);
    return copia;
}

Exemplo de Utilização

O código a seguir demonstra como utilizar a clasce para calcular a distância entre duas datas específicas.

#include "Calendario.hpp"
#include <iostream>

int main() {
    Calendario nascimento(2004, 4, 6);
    Calendario hoje(2023, 10, 13);

    int diferenca = hoje - nascimento;

    std::cout << "Data de Inicio: ";
    nascimento.exibir();
    
    std::cout << "Data Final: ";
    hoje.exibir();

    std::cout << "Total de dias decorridos: " << diferenca << std::endl;

    Calendario futuro = hoje + 100;
    std::cout << "Data apos 100 dias: ";
    futuro.exibir();

    return 0;
}

A implementação utiliza um método de cotnagem incremental para a diferença de datas, o que garante precisão ao considerar anos bissextos de forma automática através do método estático diasNoMes. Este modelo de classe é extensível e serve como base para sistemas de agendamento ou logs cronológicos.

Tags: cpp OOP OperatorOverloading DataTypes

Publicado em 7-8 21:31