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.