Dzień dobry,
obecnie zajmuje się serią Pana Zelenta o programowaniu obiektowym w C++. Realizowałem zadanie z odc. 3, gdzie trzeba było utworzyć klasę do tworzenia wydarzeń zawierających nazwę, datę, czas itd.
Stworzyłem klasę "Event" i w metodzie void show() chciałem dodatkowo wyświetlić nazwy miesięcy oraz dni tygodnia. Potrzebowałem do tego czegoś, co:
1. jest stałe (w sensie niezmienne),
2. tworzy się co najwyżej raz w całym programie, bo ma służyć tylko do odczytu,
3. i jest dostępne wyłącznie dla wybranych klas (tu jest jedna, ale zakładam możliwość dostępu dla wielu).
Po wielu próbach postawiłem na klasę singleton "MonthsAndDays" z chronionymi polami jako mapy. W funkcji main nie mogę skorzystać z żadnej metody ani pola tej klasy, więc myślę, że osiągnąłem punkt 3. Co do punktów 1 i 2 już nie mam pewności, a jedynie przypuszczenia, że tak jest. Kolejną wątpliwością jest to, czy nie dało się tego zrobić lepiej, bo nieraz słyszałem i czytałem, że raczej już się singletona nie używa.
Co do punktu 2., czy na pewno jest tak, że w momencie, gdy obiekt klasy "Event" skorzysta z klasy "MonthsAndDays" jako pierwszy, to wtedy tworzy się ta jedyna instancja i od tej chwili każdy inny obiekt z dow. klasy będzie do niej odwoływał?
I czy w ogóle ja tutaj tworzę jakąkolwiek instancję klasy "MonthsAndDay", czy jedynie odwołuje się do jej pól? (blok nr 4, funkcja show)
Main:
#include "Event.h"
#include <iostream>
using namespace std;
int main()
{
Event event;
event.show();
cout << endl;
event.load();
cout << endl;
event.show();
return 0;
}
MonthsAndDays.h:
#ifndef MonthsAndDays_H
#define MonthsAndDays_H
#include <iostream>
#include <map>
using namespace std;
class MonthsAndDays
{
protected:
const map<unsigned short, string> month_in_words=
{
{1, "stycznia"},
{2, "lutego"},
{3, "marca"},
{4, "kwietnia"},
{5, "maja"},
{6, "czerwca"},
{7, "lipca"},
{8, "sierpnia"},
{9, "wrzesnia"},
{10, "pazdziernika"},
{11, "listopada"},
{12, "grudnia"}
};
const map<unsigned short, string> weeks_day_in_words=
{
{0, "sobota"},
{1, "niedziela"},
{2, "poniedzialek"},
{3, "wtorek"},
{4, "sroda"},
{5, "czwartek"},
{6, "piatek"}
};
protected:
MonthsAndDays(){};
protected:
static MonthsAndDays &getMonthsAndDays()
{
static MonthsAndDays instance;
return instance;
}
};
#endif // MonthsAndDays_H
Event.h:
#ifndef EVENT_H
#define EVENT_H
#include "MonthsAndDays.h"
#include <iostream>
#include <map>
using namespace std;
typedef unsigned short ushort;
class Event: private MonthsAndDays
{
private:
string name;
string place;
unsigned short day, month, year;
unsigned short hour, minutes;
unsigned short weeks_day;
public:
Event(string="nazwa", string="miejsce", ushort=1, ushort=1, ushort=2000, ushort=0, ushort=0);
~Event();
void load();
void show() const;
private:
void Zellers_congruity();
unsigned short Zellers_month() const;
unsigned short Zellers_century() const;
unsigned short Zellers_century_year() const;
};
#endif // EVENT_H
Event.cpp:
#include "Event.h"
Event::Event(string name, string place, unsigned short day, unsigned short month, unsigned short year, unsigned short hour, unsigned short minutes)
{
this->name=name;
this->place=place;
this->day=day;
this->month=month;
this->year=year;
this->hour=hour;
this->minutes=minutes;
}
Event::~Event()
{
cout << endl << "Usuwanie obiektu." << endl;
}
void Event::load()
{
cout << "KREATOR WYDARZEN" << endl << endl;
cout << "Nazwa: ";
getline(cin, name);
cout << "Miejsce: ";
getline(cin, place);
cout << "Dzien miesiaca: ";
cin >> day;
cout << "Numer miesiaca: ";
cin >> month;
cout << "Rok: ";
cin >> year;
cout << "Godzina (sama godzina): ";
cin >> hour;
cout << "Minuty: ";
cin >> minutes;
Zellers_congruity();
}
void Event::show() const
{
cout << "Wydarzenie '" << name << "' odbedzie sie w miejscu " << place << " " << day << " " << MonthsAndDays::month_in_words.at(month) << " ";
cout << year << " roku" << " (" << MonthsAndDays::weeks_day_in_words.at(weeks_day) << ") " << "o godzinie " << hour << ":" << minutes << "." << endl;
}
void Event::Zellers_congruity()
{
unsigned short J=Zellers_century(), K=Zellers_century_year();
weeks_day=(day + 13*(Zellers_month()+1)/5 + J/4 + 5*J + K + K/4)%7;
}
unsigned short Event::Zellers_month() const
{
if(month<3) return month+12;
return month;
}
unsigned short Event::Zellers_century() const
{
return year/100;
}
unsigned short Event::Zellers_century_year() const
{
return year%100;
}