#include "etel.hpp"
#include <iomanip>
using namespace std;
Etel::Etel(const string& nev) // const kulcsszót, azért mert nem változtatjuk a függvényen belül.
// egyáltalán nem muszáj, csak olvashatóság + praktikus
: nev(nev),
alapanyagok() // Ez explicit módon meghívja az alapanyagok adattag
{} // (ami egy vector) alapértelmezett (üres) konstruktorát.
//Etel::Etel(const string& nev) {
// this->nev = nev;
// // alapanyagok automatikusan üres vektorral inicializálódik
//}
Etel::~Etel() { // Ha dinamikusan foglalt pointereket (tehát new-vel foglalt objektumokat)
// tárolnál, akkor mindenképpen megkell írni, lásd következő laborok
cout << "[DEBUG] Etel törölve: " << nev << endl;
}
void Etel::alapanyag_hozzaad(const Alapanyag& a, double mennyiseg_gramm) {
for (size_t i = 0; i < alapanyagok.size(); ++i) { // Klasszikus for ciklus, ahol indexeljük a vektort,
// végigmegyünk az alapanyagok vektor elemein.
pair<Alapanyag, double>& par = alapanyagok[i]; // létrehozunk egy referenciát, amin keresztül dolgozunk - explicit típus
//pair<const Alapanyag*, double>& par = alapanyagok[i]; // #2 - Ha a pointered nem const, de az emplace_back (és a pair) néha constként várja,
// fordítói implementációtól függően nem tudja, melyik konstruktort hívja.
// itt már ki kell tenni a const-ot
if (par.first.nev_get() == a.nev_get()) { // Ha már van az adott alapanyagból, csak a mennyiséget növeljük.
//if (par.first->nev_get() == a.nev_get()) {
par.second += mennyiseg_gramm;
return; // Nem is megyünk tovább ha már van belőle.
}
}
alapanyagok.emplace_back(a, mennyiseg_gramm); // Ha nincs belőle akkor csak simán hozzáadjuk. (másolatot)
//alapanyagok.emplace_back(&a, mennyiseg_gramm); // Pointer tárolásnál fontos a & operátor, csak így tudjuk átvenni helyesen
}
// Gyakorlatilag ugyanaz, mint az előző
void Etel::alapanyag_mennyiseg_novel(const string& alapanyag_nev, double gramm) {
for (auto& par : alapanyagok) { // auto kulcsszó C++11-től van, és nagyon hasznos, főleg ciklusoknál.
if (par.first.nev_get() == alapanyag_nev) { // azt mondja a fordítónak: "A változó típusát automatikusan következtesd le abból, amiből a ciklus dolgozik!"
//if (par.first->nev_get() == alapanyag_nev) { // Itt az alapanyagok egy vector<pair<Alapanyag, double>>,
par.second += gramm; // ezért a par típusa pair<Alapanyag, double>& lesz.
return; // A range-based for ciklus: minden ciklusban végigmegy az alapanyagok vektor összes elemén,
} // és a par nevű változó minden iterációban az aktuális elemre mutat (referenciaként, az & miatt).
}
}
// 1:1-ben ugyanaz, csak csökkentés
void Etel::alapanyag_mennyiseg_csokkent(const string& alapanyag_nev, double gramm) {
for (auto& par : alapanyagok) {
if (par.first.nev_get() == alapanyag_nev) {
//if (par.first->nev_get() == alapanyag_nev) {
par.second -= gramm;
if (par.second < 1) par.second = 0;
return;
}
}
}
void Etel::alapanyag_torol(const string& alapanyag_nev) {
for (auto it = alapanyagok.begin(); // Az it a nemzetközi konvenció szerinti rövidítése az "iterator" szónak.
it != alapanyagok.end(); // .begin() .end() minden STL-konténeren (pl. vector, list, map, set) működnek.
++it) { // .end() Egy speciális, az utolsó elem utáni pozícióra mutató iterátort ad vissza.
if (it->first.nev_get() == alapanyag_nev) { // az iterátor egy "mutató-szerű" objektum. - (*it).first == it->first
//if (it->first->nev_get() == alapanyag_nev) {
alapanyagok.erase(it);
return;
}
}
}
double Etel::ossz_ch() const {
double s = 0;
for (const auto& par : alapanyagok)
s += par.first.ch_get() * par.second / 100.0; // 100-al osztás, mivel 100 g-ra határoztuk meg a makrókat.
//s += par.first->ch_get() * par.second / 100.0;
return s;
}
// 1:1...
double Etel::ossz_feh() const {
double s = 0;
for (const auto& par : alapanyagok)
s += par.first.feherje_get() * par.second / 100.0;
//s += par.first->feherje_get() * par.second / 100.0;
return s;
}
double Etel::ossz_zsir() const {
double s = 0;
for (const auto& par : alapanyagok)
s += par.first.zsir_get() * par.second / 100.0;
//s += par.first->zsir_get() * par.second / 100.0;
return s;
}
double Etel::ossz_rost() const {
double s = 0;
for (const auto& par : alapanyagok)
s += par.first.rost_get() * par.second / 100.0;
//s += par.first->rost_get() * par.second / 100.0;
return s;
}
double Etel::ossz_ar() const {
double s = 0;
for (const auto& par : alapanyagok)
s += par.first.ar_get() * par.second / 100.0;
//s += par.first->ar_get() * par.second / 100.0;
return s;
}
double Etel::ossz_kcal() const {
return ossz_ch() * 4 + ossz_feh() * 4 + ossz_zsir() * 9 + ossz_rost() * 0;
}
void Etel::osszes_alapanyag_kiir() const {
cout << "Alapanyagok a(z) " << nev << " ételben:" << endl;
for (const auto& par : alapanyagok) {
cout << " - " << setw(18) << left << par.first.nev_get()
//cout << " - " << setw(18) << left << par.first->nev_get()
<< setw(5) << par.second << "g" << endl;
}
}
ostream& operator<<(ostream& os, const Etel& e) {
os << "Étel: " << e.nev << endl;
e.osszes_alapanyag_kiir();
os << "Tápérték összesen:" << endl << fixed << setprecision(1)
<< " CH: " << e.ossz_ch() << " g" << endl
<< " Fehérje: " << e.ossz_feh() << " g" << endl
<< " Zsír: " << e.ossz_zsir() << " g" << endl
<< " Rost: " << e.ossz_rost() << " g" << endl
<< " Kalória: " << e.ossz_kcal() << " kcal" << endl
<< " Ár: " << e.ossz_ar() << " Ft" << endl;
return os;
}